11
回答
java tcp 黏包分包 首部长度 的问题
华为云实践训练营,热门技术免费实践!>>>   

java 写tcp,为了解决黏包分包的问题,我选择了添加首部长度的方式:

如:|len|data|         包头放一个4个字节,表示data的数据长度

问题:

如果任何一个data里发生了丢包,是不是就会导致接下来所有的数据都无法正常接收?

假如len=100 ,而实际data就剩下了90,程序就会把下一个包的前10给读进来,这样接受的数据就会无法解析?

 

是不是存在这样的问题? 怎么解决?

 

举报
7哥
发帖于3个月前 11回/310阅
共有11个答案 最后回答: 3个月前

从应用层看TCP协议是不会发生丢包的,每次从内核缓冲区里面读到的数据都是完整的。如果这个层级上发生丢包,说明TCP协议数据重传失败,recv这个函数就该返回-1了

解决黏包最直接的思路,就是假设数据是一个字节一个字节分开发过来的。你能处理好这个情况,什么分包黏包都不是问题了。
--- 共有 4 条评论 ---
乌龟壳@7哥 回复@7哥 : tcp只保证基本的数据包正确性和数据包的顺序不乱,你想一次就能读到想要的东西tcp没保证这些。所以才有黏包分包等问题。 3个月前 回复
7哥 回复 @乌龟壳 : 数据丢了一部分,我按照长度取出来的数据不是一套完整的,这是解析不出来的。 3个月前 回复
乌龟壳@7哥 回复@7哥 : 弄个byte[]把数据先缓存着就行了,下一个字节来了后看看数据够不够,不够继续加到缓存里。够了就拿出来处理 3个月前 回复
7哥单个字节无法识别啊,要识别必须解析,要解析必须知道设定的哪几个字节是一个整体,这又得知道长度 3个月前 回复

这种情况一般是组包的时候才会出现,开发人员组包不应该出现这种错误,这种问题只会在外部连接不知道数据包结构的时候乱发一通,导致错误的数据包堆积在内存中的缓冲里面,造成服务器资源浪费或者死机,这就属于恶意攻击了。如果你的结构是 数据包长度+数据包内容,我建议你再加个数据包结束校验符,先通过长度拿到数据包内容,再验证是否存在结束校验符。还有一种更靠谱的方案就是加固定字节的包头,通过包头进行数据包容错处理。

你这只是加长度  根本就没拆包    而且还和TCP协议的拆包弄混淆了     

就你这9999个字节  一个包发过去就行了    没必要拆包       

java 已经是在socket封装过一层了 ,tcp是流传输,关于数据包 是系统底层的驱动实现,完全可以使用阻塞式io的DataOutputStream  或者nio的ByteBuffer 相应的函数来读写socket流,已经封装的很完美了,怎么写入流的就怎么读取 ,不是udp,怎么会丢一部分呢 那只可能是系统错误或者代码问题导致

黏包,谁说的概念,先研究一下网络分层模型,什么是tcp协议吧。一般串口程序才会考虑数据丢失,编写数据协议,比如命令开头标记,有这个标记就是数据开头,然后数据长度和数据,最后加一个校验位,前面数据计算得到。接受端检查命令头,根据数据长度取数据计算校验位,比较校验位是否一致。检验不通过再查找下一个命令头。
顶部