通过制定报头解决粘包问题

#1.什么是粘包?
#粘包就是在获取数据时,出现数据的内容不是本应该接收的数据,如:对方第一次发送hello,第二次发送world,
#我放接收时,应该收两次,一次是hello,一次是world,但事实上是一次收到helloworld,一次收到空,这种现象
#叫粘包
#2.出现粘包的原因:在给对方发送消息时,是先把消息发给自己的操作系统(内存),然后通过操作系统-->网络-->对方
#的操作系统,对方在到自己的操作系统中获取信息,也就是说不管是发送信息还是接收信息,我们只能是在自己的操作
#系统中进行,不是直线发送或接收对方的信息,而操作系统具有延迟性,所以出现了粘包
#3.粘包的解决,是通过设置报头,在传信息之前,先把该信息的报头传给对方,在传该信息,就不会出现粘包
#4.报头是一个字典,它含有信息的大小,还有可以有文件的名称,文件的hash值,如下
#head_dic={'size':len(data),'filename':filenaem,'hash':hash值},如果还有,可以继续在字典中加
服务端:
import struct
import subprocess
import json
import socket
phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
ip_port =('127.0.0.1',8088)
phone.bind(ip_port)
max_request_size =5
phone.listen(max_request_size)
while True:
print('starting.....')
conn,addr =phone.accept()
print('客户端的addr是:',addr)
while True:
try:
data =conn.recv(1024)
res =subprocess.Popen(data.decode('utf-8'),shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
res_out =res.stdout.read()
res_err =res.stderr.read()
#制作报头
res_size =len(res_out)+len(res_err)
head_dic ={'size':res_size,'hash':None}
head_json =json.dumps(head_dic)
head_bytes =head_json.encode('utf-8')
#先发报头的长度
head_len =len(head_bytes)
conn.send(struct.pack('i',head_len))

#在发报头
conn.send(head_bytes)
#最后发送信息
conn.send(res_out)
conn.send(res_err)
except Exception:
break

conn.close()
phone.close()
客户端
import struct
import json
import socket
phone =socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ip_port =('127.0.0.1',8088)
phone.connect(ip_port)
while True:
msg =input('>>>:').strip()
#phone.send(b'hello')
if not msg:
continue
phone.send(msg.encode('utf-8'))

#先收报头的长度
head_struct =phone.recv(4)
head_len =struct.unpack('i',head_struct)[0]

#在收报头
head_bytes =phone.recv(head_len)
head_json =head_bytes.decode('utf-8')
head_dic =json.loads(head_json)

#在收信息
data_size =head_dic['size']
recv_size =0
recv_data =b''
while recv_size <data_size:
data =phone.recv(1024)
recv_size+=len(data)
recv_data+=data

print(recv_data.decode('gbk')) #如果服务端在linux中,就用utf-8解码

phone.close()
原文地址:https://www.cnblogs.com/IQ-Python/p/6807984.html