java tcp 黏包分包 首部长度 的问题

7哥 发布于 2017/09/06 10:54
阅读 537
收藏 0

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

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

问题:

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

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

 

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

 

加载中
0
GestureWei
GestureWei

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

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

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

0
kentxp
kentxp

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

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

0
yysf
yysf

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

0
开源中国首席罗纳尔多
开源中国首席罗纳尔多

黏包是啥?怎么来的?

0
i好人大叔am
i好人大叔am

要不在前面再加一位,变成

|len_leng|len|data|

这样子len的长度就变成动态了。

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

socket通讯的时候,要定义Frame, 可以参考dubbo的RPC协议。

返回顶部
顶部