Python--網絡編程-----粘包現象
阿新 • • 發佈:2018-04-08
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 客戶端的數據 b‘dir‘ 4 453 5 客戶端的數據 b‘ipconfig‘ 6 1481 7 客戶端的數據 b‘dir‘ 8 453
可以看出,ipconfig命令結果的長度超出了recv最大接收字節數,沒有接收完,還遺留在管道裏,就出現了粘包現象
Python--網絡編程-----粘包現象