TCP数据传输粘包
- 场景
在工作中用到一个模块,一个房间,用户在其中进行聊天,视频,互动以及何种数据的传输,采用的方案是采用TCP/IP通信协议及标准的socket应用开发编程 问题
其中遇到一个现象,数据粘包,具体体现是:在一段较短的时间内,服务器向客户端发送了不止一组数据,这些数据本应该一组一组发送,但是因为TCP协议本身原因,服务器收集到一定的数据之后合成了一包发送,导致数据接收出现了问题比如:需要发送的数据为: A + B + C + D 合成一包之后接收端收到处理的只有 A ,后边的数据没有处理
原因
- a 发送方:TCP为了提高传输效率(TCP 面向连接,提供高可靠性服务,UDP无连接,提供高效率服务),往往要收集到足够多的数据后才发送一包数据,若连续几次发送的数据都少,则会优化算法把数据合成一包发送出去(这是由TCP协议本身造成的)
- b 接收方:接收方接收数据不及时导致的
解决
- a 发送方:TCP本身提供了强制数据立即传送的操作指令Push,接到这个指令则不会等缓冲区满,会立即发送
- b 接收方:优化,精简接收进程工作量,进程优先级提供
PS
UPD不会出现这种情况因为他有消息边界可以区分开,而类似的,移动端和服务器端共同商议一个边界,在移动端进行数据分割 例如: A + B + C + D ------> A$%^& + B$%^& + C$%^& + D$%^& 接收方根据$%^&来分开A,B,C,D来处理
代码
while(rangeLen.location != NSNotFound)
{
NSData *optionData = [allData subdataWithRange:NSMakeRange(0, rangeLen.location)];
NSDictionary *dic;
NSError *error = nil;
dic = [NSJSONSerialization JSONObjectWithData:optionData options:NSJSONReadingMutableContainers error:&error];
[self.delegate receiveData:error ? error.localizedDescription : dic];
NSRange temp = NSMakeRange((rangeLen.location + rangeLen.length), (allData.length-(rangeLen.location+rangeLen.length)));
allData = [allData subdataWithRange:temp];
rangeLen =[allData rangeOfData:subData options:0 range:NSMakeRange(0, allData.length)];
}