粘包现象及解决方法(Python)

TCP协议在传输数据时可能出现粘包现象,这源于TCP面向流的特性。UDP协议则无此问题,因为它面向消息。粘包主要发生在数据发送频率高、数据量小或者接收端未及时处理时。解决粘包的方法包括发送前告知数据长度,或使用固定长度的头部指示数据大小。这些方案各有优劣,需要根据具体应用场景选择。
摘要由CSDN通过智能技术生成

粘包现象及解决方法(Python)

什么是粘包

只有TCP有粘包现象,UDP没有

socket收发消息的原理


应用程序看到的数据是一个整体,或称为一个流(stream),而一条消息有多少字节对应用程序是不可见的,因此TCP协议是面向流的协议。
而UDP协议是面向消息的协议,每个UDP段都是一条消息,应用程序必须以消息为单位提取数据。
而消息可以认为发送方一次性write/send的数据为一个消息,但是,当send一条信息时,无论底层怎样分段分片,TCP协议层会把构成整条信息的数据段排序完成后才呈现在内核缓冲区。即面向流的通信是无消息保护边界的。
由于UDP支持的是一对多的模式,所以接收端的套接字缓冲区采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址、端口等信息),对于接受端来说就容易进行区分处理。即面向消息的通信是有消息保护边界的

所谓粘包问题主要是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。

此外,发送方引起的粘包是由TCP协议本身造成的,TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要发送的数据都很少,通常TCP会根据优化算法(Nagle算法)把这些数据合成为一个TCP段后一次发送出去。

两种情况下会发生粘包

1.发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据量很小,会合并到一起,产生粘包)
2.接收方不及时接收缓冲区的包,造成多个包接收(客户端发送了一段数据,服务端只收了一部分,服务端下一次接收的时候还是从缓冲区取上次遗留的数据,产生粘包)

解决粘包

1.发送端发送数据之前,先将数据长度让接收端知晓,接收端根据总长度利用循环完成消息的接收

# 客户端:

from socket import *

ip_port = ('127.0.0.1', 8000)
back_log = 5
buffer_size = 1024

tcp_client = socket(AF_INET, SOCK_STREAM)
tcp_client.connect(ip_port)


while True:
    cmd = input(">>:").strip().encode("utf-8")
    if not cmd: continue
    if cmd == 'quit': break
    tcp_client.send(cmd)                                    # 发送指令

    length = tcp_client.recv(buffer_size).decode("utf-8")   # 接收数据长度信息
    tcp_client.send(b"ready")                               # 发送确认信息

    server_result = tcp_client
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值