tcp協議產生-粘包問題的解決方案
阿新 • • 發佈:2018-07-10
import col 執行 port == pan 字符 use utf8
客戶端
1 客戶端 2 3 from socket import * 4 import json,struct 5 6 7 client=socket(AF_INET,SOCK_STREAM) 8 client.connect((‘127.0.0.1‘,8080)) 9 10 11 while True: 12 cmd=input(‘>>>‘).strip() 13 if len(cmd)==0:continue 14 client.send(cmd.encode(‘utf8‘)) 15 print(‘客戶端命令發送完畢‘)16 # 收到報頭的長度 17 header_len=struct.unpack(‘i‘,client.recv(4))[0] 18 19 # 收到報頭的字節內容 20 header_bytes=client.recv(header_len) 21 22 # 轉成字符串 23 header_str=header_bytes.decode(‘utf8‘) 24 25 # 根據json轉成字典 26 header_dic=json.loads(header_str) 27 28 # 取得文件總大小 29 total_size=header_dic[‘total_size‘] 30 31 recv_size=0 32 33 # 下面的 data 是字節,所以res也必須是字節 34 res=b‘‘ 35 while recv_size<total_size: 36 data=client.recv(1024) 37 res+=data 38 recv_size+=len(data) 39 print(res.decode(‘gbk‘)) 40 41 client.close()
服務端
1 服務端 2 3 from socket import* 4 import json,struct 5 import subprocess 6 7 server=socket(AF_INET,SOCK_STREAM) 8 server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) 9 server.bind((‘127.0.0.1‘,8080)) 10 server.listen() 11 12 while True: 13 conn,client_addr=server.accept() 14 while True: 15 try: 16 cmd=conn.recv(1024) 17 if len(cmd)==0:break 18 obj=subprocess.Popen(cmd.decode(‘utf8‘), 19 shell=True, 20 stdout=subprocess.PIPE, 21 stderr=subprocess.PIPE, 22 ) 23 stdout=obj.stdout.read() 24 stderr=obj.stderr.read() 25 # 制作字典報頭 26 header_dic={ 27 ‘file_name‘:‘07 執行python程序的兩種方式.mp4‘, 28 ‘total_size‘:len(stderr)+len(stdout), 29 ‘hash‘:‘fkjds‘ 30 } 31 # 將報頭用json 序列化 32 header_json=json.dumps(header_dic) 33 # 將json文件轉成字節 34 header_bytes=header_json.encode(‘utf8‘) 35 36 # 將報頭打包發送給客戶端 37 header=struct.pack(‘i‘,len(header_bytes)) 38 39 # 將4個字節的報頭發送給客戶端,客戶端會收到壓縮的4個字節的報頭 40 conn.send(header) 41 42 # 將字節的報頭內容發送給客戶端,因為上一步只是將報頭的長度發送給了客戶端 43 conn.send(header_bytes) 44 45 # 發送正文 46 conn.send(stdout) 47 conn.send(stderr) 48 except ConnectionResetError: 49 break 50 conn.close() 51 52 server.close()
tcp協議產生-粘包問題的解決方案