C/C++

TCP粘包处理

2018-08-24  本文已影响0人  cx7

TCP粘包

TCP发送/接收数据的方式是数据流
recv每次读取的字节 可能包含的数据包数量是不固定的

在发送端 调用send发送数据包会将数据包拷贝到TCP的发送缓冲区中
1. 缓冲区数据满 TCP将会发送缓冲区数据
2. 达到超时时间 TCP将会发送缓冲区数据

这种机制之下 可能有几种数据的发送情况
1. 数据量小于缓冲区限制大小 可能几个数据包一起发送或是单个数据包超时后发送
2. 数据量大于缓冲区限制大小 一个数据包被分割成多个数据包发送

在接收端 调用recv读取缓冲区数据时
ssize_t recv(int socket, void *buffer, size_t length, int flags);
recv需要指定读取的字节数 可能有这些情况
1. 缓冲区数据量比指定读取的字节数少 读取所有数据到缓冲区
2. 缓冲区数据量比指定读取的字节数多 读取部分数据 剩下的需要下一次recv读取

接收端和发送端的情况导致了TCP接收数据时 协议本身并不能保证数据包的独立性
你读取到的可能是单个包或是多个包 也可能是不完整的一个数据包

TCP粘包的处理

1. 定制通信协议:用自定义的起始码和数据长度来区分数据包的界限
    比如 4个字节的0x 00 00 00 01作为数据包的起始 随后4字节说明数据包的长度 再附上数据
    数据包组成: 起始码 + 数据长度 + 数据
2. 定义用户层的缓存buffer 当recv收到TCP数据时 就讲数据append到缓存buffer之后
    用户通过读取起始码和数据长度 从用户层的缓存buffer中获取一个完整的数据包
上一篇 下一篇

猜你喜欢

热点阅读