在TCP协议通信中,如果多条消息的发送间隔较短,会合在一起发送,导致消息发送端发送消息太快,接收端来不及接收消息时,就会产生粘包现象
粘包问题
示例:server.py
tcp_server = socket.socket()
tcp_server.bind(("127.0.0.1", 5060))
tcp_server.listen()
conn, addr = tcp_server.accept()
# 等待1秒之后,连续接收两条消息
time.sleep(1)
msg1 = conn.recv(1024)
print(msg1)
msg2 = conn.recv(1024)
print(msg2)
conn.close()
tcp_server.close()
示例:client.py
tcp_client = socket.socket()
tcp_client.connect(('127.0.0.1', 5060))
# 连续发送两条消息
tcp_client.send(b'saiya')
tcp_client.send(b'06')
tcp_client.close()
代码运行的结果是,服务端接收到的两条消息粘在了一起
b'saiya06'
b''
解决方案
在发送端在发送消息前,先发送一个长度包,说明将要发送的报文的长度,接收端每次在消息的时候,先从长度包中解析出报文的长度,再接收指定长度的报文
修改之后的server.py
tcp_server = socket.socket()
tcp_server.bind(("127.0.0.1", 5060))
tcp_server.listen()
conn, addr = tcp_server.accept()
# 等待1秒之后,连续接收两条消息
time.sleep(1)
byte_len = conn.recv(4) # 接收长度包
msg_len = struct.unpack('i', byte_len)[0] # 解析出报文长度
msg1 = conn.recv(msg_len) # 接收指定长度的报文
print(msg1)
byte_len = conn.recv(4) # 接收长度包
msg_len = struct.unpack('i', byte_len)[0] # 解析出报文长度
msg2 = conn.recv(msg_len)
print(msg2)
conn.close()
tcp_server.close()
修改之后的client.py
tcp_client = socket.socket()
tcp_client.connect(('127.0.0.1', 5060))
# 连续发送两条消息
msg1 = b'saiya'
byte_len = struct.pack('i', len(msg1)) # 使用struct模块,将报文长度转换为4bit的字节
tcp_client.send(byte_len) # 发送长度包
tcp_client.send(msg1) # 发送报文包
msg2 = b'06'
byte_len = struct.pack('i', len(msg2))
tcp_client.send(byte_len)
tcp_client.send(msg2)
tcp_client.close()
修改代码之后的运行结果:
b'saiya'
b'06'
标签:解决方案,len,TCP,client,tcp,byte,粘包,server,conn
From: https://www.cnblogs.com/saiya6/p/16948876.html