準備工作:
(1)OS系統:windows/linux
(2)浏覽器:隻要核心符合webkit/不建議使用ie核心的浏覽器
推薦:chrome/sogouie/360
(3)python:3.7.x
不建議使用3.7以上,一般采用3.5、3.6、3、7版本的python
(4)IDE:IDLE/VScode/記事本/文本編輯器/sublime
(5)pip tools
(6)net:網絡通暢
基本文法
資料和集合
函數和變量
.......
TCP和UDP的差別
計算機與網絡裝置互相通信,雙方就必須基于相同的方法履歷的一套通信網絡模型,需要事先約定好的通信規則稱之為協定(protocol)
TCP/IP是一系列協定族群的統稱:tcp/udp/ip/ftp/http/smtp等
這些協定可以劃分為四層:
鍊路層:負責封裝和解封IP封包,發送和接受ARP/RARP封包等
網絡層:負責路由以及分組封包發送給目标網絡和主機
傳輸層:負責對封包進行分組和重組,并以TCP或者UDP封裝封包
應用層:負責向使用者提供應用程式,http,ftp,telnet,dns,smtp等
全稱是使用者資料報協定,和TCP一樣,用于處理資料包,他是一種無連接配接協定,不提供資料包分組,組裝和不能對資料包進行排序等特點,也就是說無法得知是否安全完整的到達。
在發送端,應用層将資料傳給傳輸層的UDP協定,UDP隻會給資料增加頭辨別,識别一下是否UDP過來的資料包,然後傳輸給傳輸層
在接收端,網絡層将資料傳輸給傳輸層,UDP隻去除IP封包頭,就傳輸給應用層,不會做任何的拼接操作
UDP不僅僅隻支援一對一的傳輸,還可以支援一對多,多對多,多對一的傳輸方式
發送方對UDP對應用程式傳遞下來的封包,不會做合并和拆分,隻會添加首部和尾部後傳遞IP層
無連接配接,通信不需要建立連接配接;接受什麼資料就傳輸什麼資料;不會備份資料;發送資料不會确定接收方是否已經接收到資料;無擁塞控制,以恒定的速度進行收發,網絡出現波動會導緻丢包
比如電話傳輸,qq等
第一次握手是主要是向伺服器發送請求的封包段;第二次握手主要是伺服器接收到請求的封包段,如果同意連接配接,就會發送一個應答;第三次握手是用戶端接收到伺服器的應答後,向伺服器發送一個确認封包
TCP是一種雙全工的機制,在斷開連接配接到時候,兩端都需要發送一個ACK和FIN來給它一個狀态,在三次握手後,還有個四次揮手,在用戶端發送斷開連接配接請求給服務端;伺服器傳回收到;在所有資料傳輸完成後,伺服器再發送一次收到,并關閉連接配接;用戶端再發送一個ack表示已收到。
當發送資料的時候必須在兩端建立連接配接,建立連接配接是通過三次握手進行建立,這樣建立的是一種可靠的連接配接,為後續資料傳輸打基礎
隻能在建立了連接配接的兩端進行傳輸,不支援廣播和多點傳播
将資料轉化為位元組流,不是向UDP那種一個封包一個封包的傳輸,而是以不保留邊界的情況下,以位元組流的傳輸
為保證封包的傳輸可靠,給每個包一個序号,同時序号也是保證了傳輸到接收端的實體是按照順序進行接收的,在接收端的實體,對已成功的位元組發回一個相應的确認ACK,如果發送端的實 體未接收到确認,會重新傳輸。
當網絡出現了擁塞,tcp能減少相應網絡傳輸資料的速率和數量來緩解擁堵
TCP允許通信雙方的應用程式在任何時候都可以發送資料,TCP有緩存,是臨時存放雙向通信的資料,可以立即發送一個資料段,也可以緩存一段時間再發送資料端,主要取決于最大封包段長度(MSS)
<col>
UDP
TCP
是否連接配接
無連接配接
面向連接配接
是否可靠
不可靠
可靠
連接配接對象個數
多對多,單對單,單對多,多對單
單對單
傳輸方式
面向封包
面向位元組流
首部開銷
開銷小,8/位元組
最小20個,最大60個位元組
使用場景
實時應用
要求可靠傳輸的,如檔案下載下傳
TCP伺服器的實作
注意:該伺服器能獲得本主機的主機名和打開12345端口,可以實作TCP連接配接
TCP用戶端的實作
python實作UDP伺服器
python實作UDP用戶端
python執行shell/cmd指令
os.system('指令字元'):傳回結果和執行的狀态碼:0[成功]/1[失敗]
os.popen('指令字元'):傳回的是執行結果,沒有執行狀态,這樣可以将擷取的結果傳回到一個list對象中
可用來做shell執行的一種方法,在搭建了tcp或者udp後,可以執行os.popen()來執行作業系統的一些指令
getoutput("指令字元")
getstatusoutput('指令字元')
shell執行:
os.system('./hello.sh')
shell中的參數的使用
shell,檔案名:run.sh , 内容:echo "hello world ${1}${2}" //第一個變量為${1}第二個為${2}
sh run.sh hello python //第一個變量為hello,第二個變量為python
python:
arg0 = input("請輸入第一個參數") #'hello'
arg1 = input('請輸入第二個參數') # 'python'
os.system('./run.sh '+arg0+' ' +arg1)
實作一個TCP的原創執行CMD/Shell指令的工具
#建立一個tcp控制伺服器,能夠實作接收來自于用戶端的指令,并執行後,将結果原樣傳回給用戶端
from socket import * #将所有的socket子產品都導入
import os #導入os子產品
#建立一個socket對象
tcpserversocket = socket(AF_INET,SOCK_STREAM)
#綁定本地資訊
addr = (' ',12345)#前一個是IP位址,後一個是端口
tcpserversocket.bind(addr) #将IP位址和端口綁定為一個套接字
tcpserversocket.listen(5) #表示能同時運作的程序為5個,listen函數使用主動連接配接套接口變為被連接配接套接口,使得一個程序可以接受其它程序的請求,進而成為一個伺服器程序
while True:
#如果有新的用戶端連接配接上來,那麼久産生一個新的套接字對象用于專為這個用戶端服務
newsocket,clientSocket = tcpserversocket.accept() #與listen監聽對應,在監聽到新的用戶端連接配接後,進行接收
#接收對用戶端發送過來的資料,最大接收的位元組為4096
cmd = newsocket.recv(4096)
#判斷cmd裡面是否有東西
if len(cmd)>0:
print("clint:"+cmd.decode('utf-8')) #将cmd裡面的内容強制轉換為utf-8列印
#将cmd裡面的資料放到os子產品中去執行
res = os.popen(cmd.decode('utf-8'),'r').read()
#将執行的結果發送給用戶端
newsocket.send(res.encode().encode('utf-8'))
#一定要關閉指令
res.close()
else:
break
newsocket.close()
#簡易版的SSH用戶端實作
from socket import *
import os
#建立socket
tcpClientSocket = socket(AF_INET,SOCK_STREAM)
#連接配接伺服器-可改良為參數化的方式
serAddress = ('127.0.0.1',12345)
tcpClientSocket.connect(serAddress) #連接配接伺服器
#提示使用者輸入指令
sendCmd = input("請輸入指令:")
if len(sendCmd)>0:
#判斷是否有内容
tcpClientSocket.send(sendCmd.encode('utf-8'))
#接收來自于伺服器的執行結果
recv = tcpClientSocket.recv(4096)
print(recv.decode('utf-8'))
#關閉socket
socket.close()
實作一個UDP主機發現工具:Windows/Linux的包嗅探
大部分作業系統在處理UDP閉合端口時,存在一種共性行為,我們可以通過這種行為來确定某個IP位址上是否存在主機存活
icmp,指定目标端口不可達,通過該資訊就可以知道目标是否存活
為什麼是使用UDP,是因為UDP可以對整個子網進行資訊發送,然後等待相應的ICMP響應傳回,而且這個過程沒有什麼開銷
目标是一款簡單的對在Windows/Linux上運作的網絡主機發現工具
還可以調用Nmap對發現的任何主機進行完整的端口掃描,用于判斷對他們進行網絡攻擊的可能性
注:在Windows中必須采取管理者模式才能通路
#網絡發現工具-嗅探器
import socket
import os
#監聽的主機IP,監聽那個網絡端口
host = '192.168.80.128'
#建立原始的套位元組,綁定到公開的接口上
#相容Windows和Linux(windows平台能支援所有的通路,Linux平台隻支援ICMP,是以才需要使用if和else)
if os.name =='nt':
socket_protocol = socket.IPPROTO_IP#允許嗅探IP的所有資料包
socket.protocol = socket.IPPROTO_ICMP#隻允許ICMP的資料包
sniffer = socket.socket(socket.AF_INET,socket.SOCK_RAW,socket_protocol) #SOCK_RAW和send一樣,意思是有套接字
#綁定端口為0,表示監聽所有端口
sniffer.bind((host,0)) #0表示所有端口
#設定捕獲資料包中包含的IP頭
sniffer.setsockopt(socket.IPPROTO_IP,socket.IP_HDRINCL,1)
#設定啟動混合模式
if os.name == 'nt':
sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_ON) #如果是Linux模式需要使用的混合模式
#讀取到的單個資料包
while True: #可以設定不斷讀取發送的資料包
print(sniffer.recvfrom(65565))
#需要在Windows平台上半閉混合模式
sniffer.ioctl(socket.SIO_RCVALL,socket.RCVALL_OFF)#使用Windows模式,需要關閉混合模式
python實作HTTP伺服器并控制伺服器
#速成版的HTTP伺服器
import tornado.web
import tornado.ioloop
#伺服器由兩個部分組成,一個是伺服器(類似于apache/nginx),一個是應用(webapp)
#應用requesthandler
#定義一個視圖類
class mainHandler(tornado.web.RequestHandler):
# tjg重寫requesthandler中的方法
# 一般情況下,http有兩種請求方法
# get:url請求,友善但不安全
# post:隐形請求,不友善但相對安全
def get(self):
# 當使用者是通過url方式請求過來的,就通過這個方法
self.write("get")
def post(self):
# 當使用者是通過post方式請求過來的,就通過post方法
self.write("post")
class chatHandler(tornado.web.RequestHandler):
#tjg重寫requesthandler中的方法
#一般情況下,http有兩種請求方法
#get:url請求,友善但不安全
#post:隐形請求,不友善但相對安全
#當使用者是通過url方式請求過來的,就通過這個方法
self.write("get chat")
#當使用者是通過post方式請求過來的,就通過post方法
self.write("post chat")
#定義一個應用
def makeapp():
#關聯通路規則,主要通過url位址來判斷進入到哪一個視圖類
return tornado.web.Application([
(r"/", mainHandler), (r"/chat", chatHandler)
])
#配置
if __name__ == "__main__":
#程式入口
app = makeapp()
app.listen(8888,address='127.0.0.1') #設定你需要通路的位址和端口
tornado.ioloop.IOLoop.current().start()
定義端口:tornado,options
擷取使用者送出過來的内容
#實作參數化啟動http的服務
from tornado.web import RequestHandler,Application
from tornado.ioloop import IOLoop
from tornado.options import options,parse_command_line,define
from tornado.httpserver import HTTPServer
#定義端口變量
define('port',default=8888,help='this is port')
#定義一個視圖
class IndexHandler(RequestHandler):
#重寫get方法
#這裡可以接收來自與URL中的參數和值,在url中參數連接配接為&
self.write("12312")
cmd = self.get_query_argument('cmd','') #獲得參數,第一個是參數名,第二個是預設值(預設為空)
run = self.get_query_argument('run','0')
print(cmd)
print(run)
self.write('cmd value=' +cmd) #通過+進行連接配接,連接配接符
#将值傳回到頁面
return Application({
(r'/',IndexHandler)
})
if __name__ == '__main__':
#開始接收監聽指令行的參數資料,參數資料需要經過define定義
parse_command_line()
#web應用
#将app部署到http伺服器
server = HTTPServer(app)
#綁定配置-端口
server.bind(options.port) #設定的預設端口為8888,但是可以直接輸入端口
#啟動server
server.start()
#啟動輪詢監聽
IOLoop.current().start()
# 簡單版的webshell
#這裡可以接收來自于URL中的參數和值,方法有兩個參數,一個是url中的參數名,第二個參數為預設值
cmd = self.get_query_argument('cmd','')
print("接收到的指令内容是:"+cmd)
#在此處執行指令
rs = os.popen(cmd,'r') #執行權限為r
#将傳回值傳回到頁面
self.write('<font color=red>【'+cmd+'】執行結果為:</font></br>')
self.write(rs.read())
return Application([
if __name__ =='__main__':
server.bind(options.port)
# webshell的pythonhttpserver
#定義視圖類——用于呈現界面
#當使用者通路預設頁面,直接傳回webshell界面
#write裡面的内容是壓縮後的前端頁面,采用html線上壓縮方式壓縮
self.write('<!DOCTYPE html><html><head><meta charset="utf-8"><title>webshell</title><style>*{padding:0;margin:0}html,body{height:100%;width:100%}.warp_panel{height:100%;width:100%;background-color:#000000}.showresult{height:95%;width:100%}.inputpanel{height:5%;width:100%;background-color:#FFFFFF;display:flex}.showresult>textarea{height:100%;width:100%;overflow:auto;border:none;background-color:initial;color:#FFFFFF}.inputpanel>input:nth-of-type(1){height:100%;width:90%;border:none}.inputpanel>input:nth-of-type(2){height:100%;width:10%;border:none}</style><script>function b(){var cmdvalue=document.getElementById("inputcmd");if(cmdvalue.value==""){alert("指令不能為空")}else{var xmlhttp=new XMLHttpRequest();xmlhttp.open("GET","/cmd?cmd="+cmdvalue.value,true);xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState===4){if(xmlhttp.status===200){var si=document.getElementById("showinfo");si.innerHTML=xmlhttp.responseText}else if(xmlhttp.status===404){}else{}}};xmlhttp.send(null);cmdvalue.value=""}}</script><!--兩種方式送出,點選按鈕送出和按回車送出--></head><body><div class="warp_panel"><div class="showresult"><textarea id="showinfo"></textarea></div><div class="inputpanel"><input type="text"id="inputcmd"placeholder="請輸入指令:"/><input type="button"value="送出"onclick="b()"/></div></div></body></html>')
#定義視圖類——用于接收并傳回資料
class CmdHandler(RequestHandler):
#接收url中的資料,并傳回cmd執行的結果
cmd = self.get_query_argument("cmd","")
#執行cmd
rs = os.popen(cmd,'r')
#傳回資料
rs.close()
(r'/',IndexHandler),(r'/cmd',CmdHandler)
#開始接收并監聽指令行的參數資料
#webapp
#将app部署到伺服器中
#綁定端口
注:所有的前端代碼在壓縮的時候都需要采用雙引号,而不能使用單引号,因為後面壓縮後的代碼回合python語句起沖突。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>webshell</title>
<style>
*{
padding:0;
margin:0;
}
html,body{
height:100%;
width:100%;
.warp_panel{
background-color:#000000;
.showresult{
height:95%;
.inputpanel{
height:5%;
background-color: #FFFFFF;
display: flex;
.showresult>textarea{
height: 100%;
width: 100%;
overflow: auto;
border: none;
background-color: initial;
color: #FFFFFF;
.inputpanel>input:nth-of-type(1){
width: 90%;
.inputpanel>input:nth-of-type(2){
width: 10%;
</style>
<script>
//按鈕的控制方法
function b(){
//擷取輸入框的内容
var cmdvalue = document.getElementById("inputcmd");
//console.log(cmdvalue.value);
if(cmdvalue.value==""){
alert("指令不能為空");
}else{
//内容不為空
//送出邏輯
//通過url向伺服器請求——異步請求技術(在頁面不重新整理的情況,送出資料到背景)
//原生的異步對象——xmlhttprequest
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","/cmd?cmd="+cmdvalue.value,true);
xmlhttp.onreadystatechange = function(){
//當請求執行後,會觸發該方法
if(xmlhttp.readyState===4){
if(xmlhttp.status===200){
//console.log(xmlhttp);
//請求成功
var si = document.getElementById("showinfo");
si.innerHTML = xmlhttp.responseText;
}else if(xmlhttp.status===404){
//找不到
//執行失敗
};
xmlhttp.send(null);
//送出完後,需要清空輸入框
cmdvalue.value = "";
</script>
<!-- 兩種方式送出,點選按鈕送出和按回車送出 -->
</head>
<body>
<div class="warp_panel">
<div class="showresult">
<textarea id="showinfo"></textarea>
</div>
<div class="inputpanel">
<input type="text" id="inputcmd" placeholder="請輸入指令:" />
<input type="button" value="送出" onclick="b()"/>
</body>
</html>
websocket介紹及結構預覽
早期是一種長輪詢,短輪詢:是伺服器向用戶端主動發送資訊,時間長短不同分類
長輪詢用到ajax異步請求方式,一次請求為一次輪詢
ws:普通的websocket
wss:加密的
websocket節約伺服器帶寬,實作即時通信
tornado架構:龍卷風主要就是為了實作實時通信建立的
websockethandler
open:當有使用者連接配接上伺服器時,主動出發該方法
on_message:當使用者向伺服器發送消息時候,主動觸發該方法
on_error:當通信有錯時,觸發該方法
on_close:當使用者下線時,觸發該方法
onopen:當使用者連接配接成功,伺服器傳回一個狀态,觸發該方法,可以證明是否連接配接到伺服器
onmessage:當服務端向用戶端發送消息時,觸發該方法
onerror:在通信過程中出錯時,觸發該方法
onclose:使用者下線或斷開連接配接時,觸發該方法
python實作即時通信伺服器并控制伺服器
python實作對資料庫的基本操作
文本存儲:txt,ini,xml,json
資料檔案:bat
資料庫存儲:關系型資料庫:MySQL,SQL server
sqlite:字尾為xxx.db,免安裝,易操作,一個sqlite3标準的資料庫檔案,符合SQL的文法操作規則
能快速實作一個程序内的資料庫系統,能自給自足,無伺服器,零配置,滿足事務型資料庫引擎,是一個完整的資料庫系統
免安裝,存放于硬碟中,輕量級,完全相容ACID,允許從多個程序或線程安全通路
完全支援sql92标準的大多數語言功能
支援的平台包括:unix:Linux,macos,Android,iOS;Windows:win32 ,wince,winrt;
支援DDL,DQL,DML