码迷,mamicode.com
首页 > 其他好文 > 详细

socket编程 粘包和半包 问题的及处理

时间:2018-10-06 20:37:36      阅读:414      评论:0      收藏:0      [点我收藏+]

标签:字节   nbsp   tcp协议   解析   就是   粘包   1.3   字符处理   \n   

一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系。

粘包 为x.5个包

半包 为0.5个包

由于网络原因 一次可能会来 0.5/1 /2/ 2.5/ 。。。。个包

当接收到时 要先看看那这个包中有多少个完整的包。把完整的包都处理了 也就是说把x都处理了。剩下的0.5留在接收区中,等待下次接收。

这回接收到的就是0.5+1.5/0.5+1.3/0.5+0.5..... 把完整的包都处理了,有残缺的扔掉 0.8的。

一般情况 接收到正确的后都要给发送端一个应答。不给应答的算超时,发送端将重发。

有头没尾的不能扔

没头有尾的可以扔

有头有尾但缺东西可以扔

有头有尾不缺东西不能扔

 

之所以出现粘包和半包现象,是因为TCP当中,只有流的概念,没有包的概念.

可以使用UDP协议.这样可以就可以区分每个包了.但是要确保包的丢失处理.为了提到效率,可以考虑写一个滑动窗口进行收发包.

若采用TCP协议进行传输,就要将每个包区分开来.可以有三种方式.因为TCP是面向流的.流只有打开和关闭,你要用一个流传输多个包,那就要向办法区分出每个包.

一:: 可以每次发送同样大小的包,过大的包不予发送,过小的包,后面部分用固定的字符‘\0‘进行填充.

二:: 将流按字符处理,抽出一个字符做转义字符(通常Java用‘\‘来做转义字符,比如"\n"表示换行).假如就设‘\‘为转义字符,发送方如果流当中出现‘\‘,就在后面在追加一个‘\‘,如果包结束,则用‘\‘做包的结束符.这样,在接收方,若读取一个单独的‘\‘或者流结束,就标示前面的内容构成一个包,如果连续读取两个‘\‘,就将两个‘\‘用一个‘\‘进行替换.这样,就可以保证原来包中的信息不变,同时也能区分出每个包了.

三:: 在发送方发送一个包的时候,先将这个包的长度发送给对方(一般是4个字节表示包长),然后再将包的内容发送过去.接收方先接收4个字节,看看包的长度,然后按照长度来接收包,这样就不会出错了. 以上三种方法,是网络传输中经常用到的方法.后两种很常见.最后一种,在TCP长连接传输中应用最多. 综合以上的说法,就是要在TCP协议以上再封装一层协议,用来做分包的信息交换. 

 

一般处理是: 一个BUFFER,用于保存当前连接的读缓存

有数据时,Buffer = Buffer + DataIn,不停的接收

收完成后,开始解析Buffer,

根据包的协议,不停的解析Buffer,并形成一个个包进行处理,处理后,Buffer = Buffer - Data,并继续解包

完成。

 

socket编程 粘包和半包 问题的及处理

标签:字节   nbsp   tcp协议   解析   就是   粘包   1.3   字符处理   \n   

原文地址:https://www.cnblogs.com/panchanggui/p/9748204.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!