首页 > 其他分享 >TCP协议中的粘包问题及解决方案

TCP协议中的粘包问题及解决方案

时间:2022-12-03 22:12:49浏览次数:41  
标签:解决方案 len TCP client tcp byte 粘包 server conn

在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

相关文章