tcp协议产生-粘包问题的解决方案

客户端

 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()

猜你喜欢

转载自www.cnblogs.com/Smart1san/p/9286369.html