专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
蚂蚁技术AntTech  ·  论文秀Live#21 ICSE 2025 ... ·  16 小时前  
OSC开源社区  ·  苹果用Swift重写每天数十亿次请求的Jav ... ·  2 天前  
程序猿  ·  雷军删文,热搜第一! ·  6 天前  
51好读  ›  专栏  ›  OSC开源社区

解 Bug 之路 —— TCP 粘包 Bug

OSC开源社区  · 公众号  · 程序员  · 2017-04-22 08:32

正文

请到「今天看啥」查看全文



上面的代码首先从报文前4个字节中获取到报文长度,同时检测在buffer中的存留数据是否够报文长度。


为何没有在一开始检测buffer中是否有足够的4byte字节呢。此处有蹊跷。直觉上就觉的是这导致了后来的种种现象。


事实上,在笔者解决各种Bug的过程中,经常通过猜想等手段定位出Bug的原因。但是从现场取证,通过证据去解释发生的现象,通过演绎去说服同事,并对同事提出的种种问题做出合理的解释才是最困难的。


猜想总归是猜想,必须要有实锤,没有证据也说服不了自己。


为何会抛出异常

这个异常由这句代码抛出:


从上面的Mina框架Dump出的数据来看,是解析前四个字节出了问题,前4个字节为30,31,2E,01(16进制)


最前面的包长度是通过字符串来表示的,翻译成十进制就是48、49、46、1,再翻译为字符串就是('0','1', 非数字, 非数字)



很明显,解析字符串的时候遇到前两个byte,0和1可以解析出来,但是遇到后面两个byte就报错了。至于为什么是For input String,'01',而不是2E,是由于传输用的是小端序。


为何报文会出现非数字的字符串

鉴于上面的错误代码,笔者立马意识到,应该是粘包了。这时候就应该去找发生Bug的最初时间点的日志,去分析为何那个时间会粘包。


由于最初那个错误日志Dump数来的数据过于长,在此就不贴出来了,以下示意图是笔者当时人肉decode的结果:


抛出的异常为:


这个异常抛出点恰恰就在笔者怀疑的


这里。至此,笔者就几乎已经确定是这个Bug导致的。



演绎


Mina框架在Buffer中解帧,前5帧正常。但是到第六帧的时候,只有两个字节,无法组成报文的4byte长度头,而代码没有针对此种情况做处理,于是报错。为何会出现这种情况:







请到「今天看啥」查看全文