1. 程式人生 > >Python--網絡編程-----粘包現象

Python--網絡編程-----粘包現象

socket network err inter 防止 RR gpo 正常 starting

一、為了防止出現端口占用的情況,

linux中可以使用pkill -9 python

windows系統中使用taskkill python

二、什麽是粘包現象

1、多個包(也就是多個命令的執行結果)粘在一起的現象,叫做粘包現象

2、代碼示例如下:

服務端代碼:

 1 import socket
 2 import subprocess
 3 
 4 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 5 # phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1
) 6 phone.bind((127.0.0.1, 9081)) # 0-65535:0-1024給操作系統使用 7 phone.listen(5) 8 9 print(starting......) 10 while True: # 鏈接循環 11 conn, client_addr = phone.accept() 12 print(client_addr) 13 14 while True: # 通信循環 15 try: 16 # 1、收命令 17 cmd = conn.recv(1024
) 18 if not cmd: # 適用於linux操作系統 19 break 20 print(客戶端的數據, cmd) 21 22 # 2、執行命令,拿到結果 23 obj = subprocess.Popen(cmd.decode(utf-8), shell=True, 24 stdout=subprocess.PIPE, 25 stderr=subprocess.PIPE)
26 27 stdout = obj.stdout.read() 28 stderr = obj.stderr.read() 29 # 3、把命令的結果返回給客戶端 30 print(len(stdout) + len(stderr)) 31 conn.send(stdout+stderr) 32 33 except ConnectionResetError: # 適用於Windows操作系統 34 break 35 36 conn.close() 37 38 phone.close()

客戶端代碼:

 1 import socket
 2 
 3 
 4 phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 5 
 6 phone.connect((127.0.0.1, 9081))
 7 
 8 while True:
 9     # 1、發命令
10     cmd = input(>>:).strip()
11     if not cmd:
12         continue
13     phone.send(cmd.encode(utf-8))
14 
15     # 2、拿命令的結果,打印
16     data = phone.recv(1024)
17     print(data.decode(gbk))
18 
19 phone.close()

在客戶端依次輸入dir,ipconfig,dir,

客戶端運行結果為:

 1 C:\Users\xu516\PycharmProjects\Python全棧開發\venv\Scripts\python.exe "C:/Users/xu516/PycharmProjects/Python全棧開發/第三模塊/網絡編程/04 粘包現象/客戶端.py"
 2 >>:dir
 3  驅動器 C 中的卷是 OS
 4  卷的序列號是 7849-BAF9
 5 
 6  C:\Users\xu516\PycharmProjects\Python全棧開發\第三模塊\網絡編程\04 粘包現象 的目錄
 7 
 8 2018/04/07  22:17    <DIR>          .
 9 2018/04/07  22:17    <DIR>          ..
10 2018/04/05  21:18                 0 __init__.py
11 2018/04/07  22:17               376 客戶端.py
12 2018/04/07  22:17             1,194 服務端.py
13                3 個文件          1,570 字節
14                2 個目錄 36,304,265,216 可用字節
15 
16 >>:ipconfig
17 
18 Windows IP 配置
19 
20 
21 無線局域網適配器 本地連接* 3:
22 
23    媒體狀態  . . . . . . . . . . . . : 媒體已斷開連接
24    連接特定的 DNS 後綴 . . . . . . . : 
25 
26 以太網適配器 VMware Network Adapter VMnet1:
27 
28    連接特定的 DNS 後綴 . . . . . . . : 
29    本地鏈接 IPv6 地址. . . . . . . . : fe80::5d54:4c1:d7d6:c647%6
30    IPv4 地址 . . . . . . . . . . . . : 192.168.189.1
31    子網掩碼  . . . . . . . . . . . . : 255.255.255.0
32    默認網關. . . . . . . . . . . . . : 
33 
34 以太網適配器 VMware Network Adapter VMnet8:
35 
36    連接特定的 DNS 後綴 . . . . . . . : 
37    本地鏈接 IPv6 地址. . . . . . . . : fe80::680e:7f79:aed1:fe62%10
38    IPv4 地址 . . . . . . . . . . . . : 192.168.254.1
39    子網掩碼  . . . . . . . . . . . . : 255.255.255.0
40    默認網關. . . . . . . . . . . . . : 
41 
42 無線局域網適配器 WLAN:
43 
44    連接特定的 DNS 後綴 . . . . . . . : DHCP HOST
45    本地鏈接 IPv6 地址. . . . . . . . : fe80::9c84:419c:e3af:89dd%11
46    IPv4 地址 . . . . . . . . . . . . : 192.168.0.106
47    子網掩碼  . . . . . . . . . . . . : 255.255.255.0
48    
49 >>:dir
50 默認網關. . . . . . . . . . . . . : 192.168.0.1
51 
52 以太網適配器 藍牙網絡連接:
53 
54    媒體狀態  . . . . . . . . . . . . : 媒體已斷開連接
55    連接特定的 DNS 後綴 . . . . . . . : 
56 
57 隧道適配器 Teredo Tunneling Pseudo-Interface:
58 
59    連接特定的 DNS 後綴 . . . . . . . : 
60    IPv6 地址 . . . . . . . . . . . . : 2001:0:9d38:953c:20d3:83ef:d86a:f024
61    本地鏈接 IPv6 地址. . . . . . . . : fe80::20d3:83ef:d86a:f024%2
62    默認網關. . . . . . . . . . . . . : ::
63 
64 >>:

第一次輸入dir顯示結果正常,第二次輸入dir輸出結果卻為ip地址信息,也就是上一個ifconfig命令的遺留信息,這種現象就叫做粘包現象,

代碼中服務端和客戶端recv指定的最大接收字節數都為1024個字節,我們可以在服務端上看看命令執行結果的長度,如下:

1 starting......
2 (127.0.0.1, 60296)
3 客戶端的數據 bdir
4 453
5 客戶端的數據 bipconfig
6 1481
7 客戶端的數據 bdir
8 453

可以看出,ipconfig命令結果的長度超出了recv最大接收字節數,沒有接收完,還遺留在管道裏,就出現了粘包現象

Python--網絡編程-----粘包現象