您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)PyThon3中網(wǎng)絡(luò)編程基礎(chǔ)實(shí)例,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
編寫一個(gè)最簡單的Client/Server程序:
1、首先執(zhí)行下面命令開啟一個(gè)監(jiān)聽8000端口的HTTP服務(wù)器:
python3 -m http.server 8000
Serving HTTP on 0.0.0.0 port 8000 ...
2、接著編寫一個(gè)程序,來對這個(gè)服務(wù)器發(fā)起HTTP請求:
import requests r = requests.get('http://127.0.0.1:8000/') print(r)
3、再執(zhí)行這個(gè)程序:
bash-3.2$ python test.py <Response [200]>
顯示服務(wù)器返回了一個(gè)200成功響應(yīng)。
現(xiàn)在我們來總結(jié)請求過程:
客戶端向服務(wù)器端發(fā)起了一個(gè)HTTP(GET)請求。
服務(wù)器端向客戶端返回了一個(gè)HTTP(200)響應(yīng)。
這是我們能看到的最抽象的過程,下面再用tcpdump細(xì)看發(fā)生了什么:
在命令行用tcpdump來監(jiān)聽本地網(wǎng)卡的tcp連接。
tcpdump -i lo0 port 8000
再通過wireshark來觀察結(jié)果:
tcpdump -i lo0 port 8000 -w test.cap
現(xiàn)在執(zhí)行程序:
bash-3.2$ python test.py <Response [200]>
得到結(jié)果:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on lo0, link-type NULL (BSD loopback), capture size 262144 bytes 23:46:06.464962 IP localhost.49329 > localhost.irdmi: Flags [S], seq 1191154495, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 178410641 ecr 0,sackOK,eol], length 0 23:46:06.465018 IP localhost.irdmi > localhost.49329: Flags [S.], seq 1405387906, ack 1191154496, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 178410641 ecr 178410641,sackOK,eol], length 0 23:46:06.465029 IP localhost.49329 > localhost.irdmi: Flags [.], ack 1, win 12759, options [nop,nop,TS val 178410641 ecr 178410641], length 0 23:46:06.465039 IP localhost.irdmi > localhost.49329: Flags [.], ack 1, win 12759, options [nop,nop,TS val 178410641 ecr 178410641], length 0 23:46:06.465065 IP localhost.49329 > localhost.irdmi: Flags [P.], seq 1:146, ack 1, win 12759, options [nop,nop,TS val 178410641 ecr 178410641], length 145 23:46:06.465079 IP localhost.irdmi > localhost.49329: Flags [.], ack 146, win 12754, options [nop,nop,TS val 178410641 ecr 178410641], length 0 23:46:06.467141 IP localhost.irdmi > localhost.49329: Flags [P.], seq 1:156, ack 146, win 12754, options [nop,nop,TS val 178410642 ecr 178410641], length 155 23:46:06.467171 IP localhost.49329 > localhost.irdmi: Flags [.], ack 156, win 12754, options [nop,nop,TS val 178410643 ecr 178410642], length 0 23:46:06.467231 IP localhost.irdmi > localhost.49329: Flags [P.], seq 156:5324, ack 146, win 12754, options [nop,nop,TS val 178410643 ecr 178410643], length 5168 23:46:06.467245 IP localhost.49329 > localhost.irdmi: Flags [.], ack 5324, win 12593, options [nop,nop,TS val 178410643 ecr 178410643], length 0 23:46:06.467313 IP localhost.irdmi > localhost.49329: Flags [F.], seq 5324, ack 146, win 12754, options [nop,nop,TS val 178410643 ecr 178410643], length 0 23:46:06.467331 IP localhost.49329 > localhost.irdmi: Flags [.], ack 5325, win 12593, options [nop,nop,TS val 178410643 ecr 178410643], length 0 23:46:06.468442 IP localhost.49329 > localhost.irdmi: Flags [F.], seq 146, ack 5325, win 12593, options [nop,nop,TS val 178410644 ecr 178410643], length 0 23:46:06.468479 IP localhost.irdmi > localhost.49329: Flags [.], ack 147, win 12754, options [nop,nop,TS val 178410644 ecr 178410644], length 0
通過結(jié)果可得:
客戶端發(fā)起一個(gè)SYN報(bào)文,向服務(wù)器請求建立一個(gè)TCP連接。
服務(wù)器端返回一個(gè)SYN+ACK報(bào)文,表示服務(wù)器收到了客戶端傳來的請求,并同意與客戶端建立TCP連接。
客戶端返回一個(gè)ACK報(bào)文,表示已經(jīng)知道服務(wù)器同意建立TCP連接,這時(shí)候雙方開始通信。
客戶端和服務(wù)器端不斷地交換信息,接收報(bào)文,返回應(yīng)答。
最后數(shù)據(jù)傳輸完畢,服務(wù)器發(fā)起一個(gè)FIN報(bào)文,表示要結(jié)束通信,客戶端返回一個(gè)ACK應(yīng)答,接著又發(fā)送一個(gè)FIN報(bào)文,最后服務(wù)器端返回一個(gè)ACK應(yīng)答,此時(shí)連接過程結(jié)束。
現(xiàn)在再來看服務(wù)器端的狀態(tài),通過lsof命令來查看綁定8000端口的描述符信息:
lsof -n -i:8000 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME python3.4 1128 tonnie 4u IPv4 0x17036ae156ec58cf 0t0 TCP *:irdmi (LISTEN)
現(xiàn)在用剛才的例子來解釋TCP中狀態(tài)遷移的概念,這時(shí)候,如果從客戶端到來一個(gè)請求:
服務(wù)器端接收到客戶端的SYN報(bào)文,返回SYN+ACK報(bào)文,服務(wù)器端進(jìn)入SYN_RCVD狀態(tài)。 服務(wù)器端收到客戶端返回的ACK應(yīng)答后,連接建立,進(jìn)入ESTABLISHED狀態(tài)。 服務(wù)器端的數(shù)據(jù)傳輸完畢,給客戶端發(fā)送FIN報(bào)文,進(jìn)入FIN_WAIT_1狀態(tài)。 服務(wù)器端接收到客戶端返回的ACK應(yīng)答后,進(jìn)入FIN_WAIT_2狀態(tài)。 服務(wù)器端接收到客戶端的FIN報(bào)文,接著返回一個(gè)ACK應(yīng)答,等待連接關(guān)閉,進(jìn)入TIME_WAIT狀態(tài)。 服務(wù)器端經(jīng)過2MSL時(shí)間后進(jìn)入CLOSED狀態(tài),此時(shí)連接關(guān)閉。
在上面的程序中,客戶端與服務(wù)器端的通信都要經(jīng)過四個(gè)層(應(yīng)用層、傳輸層、網(wǎng)絡(luò)層、網(wǎng)絡(luò)接口層)來打交道。那么這段Python程序都是通過socket操作連接的建立和關(guān)閉以及數(shù)據(jù)的傳輸?shù)纫幌盗蟹椒ā?/span>
客戶端最簡化代碼:
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('127.0.0.1', 8000)) sock.send(b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8000\r\n\r\n') data = sock.recv(4096) print(data) sock.close()
服務(wù)器端最簡化代碼:
import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('127.0.0.1', 8000)) sock.listen(5) while 1: cli_sock, cli_addr = sock.accept() req = cli_sock.recv(4096) cli_sock.send(b'hello world') cli_sock.close()
關(guān)于PyThon3中網(wǎng)絡(luò)編程基礎(chǔ)實(shí)例就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。