Netty接收超过1024字节 |
您所在的位置:网站首页 › bonding模式如何配置 › Netty接收超过1024字节 |
应用场景
使用 Netty 创建 TCP 服务器,和底层硬件进行TCP 交互,底层每次传输1026个字节。 问题描述及复现但是Netty的TCP服务端接收数据时,第一包只能接收1024个字节,第二包接收2字节。于是猜测是不是 Netty 有什么配置,将字节缓冲区设置成了 1024。于是到百度上查,有的人说将ChannelOption.SO_BACKLOG 设置成单次包传输的字节大小(在我这就是1026)。实际测试情况表明这并不是问题的解决办法。 于是我尝试着发送2056个字节过去,并打印每次接收的数据大小,结果如下 第一条日志是 1024 字节,第二条日志是 1032 字节。这两次实际上是底层硬件的第一次上传,被 Netty 分包了。 第三条日志对应客户端第二次上传数据。 第四条日志对应客户端第三次上传数据。 追踪问题原因可以看到,对于客户端的三次数据上传,Netty 分配的缓冲区大小不是固定的!猜测可能是 Netty 为了节省内存开销而设计的这种机制,接下来进入断点定位问题。 它在被构建的时候指定了三个参数。而nextReceiveBufferSize就是在此处被初始化的。 这里可以看到,这个类就是实现可变缓冲区大小的。如果上次填满缓冲区,则下次会创建一个更大的缓冲区。Netty 在初始化时,创建了一个缓冲区大小空间值的数组。 在 Channel被创建时,会调用 AdaptiveRecvByteBufAllocator 的 newHandle 方法。此时指定的缓冲区大小默认为 1024 如果说 Netty 默认提供了一个可变的缓冲区大小分配方案,那么我们可不可以改变这个策略呢?从AdaptiveRecvByteBufAllocator开始向上找到根类型,可以最终找到 RecvByteBufAllocator 接口上,查看这个接口的子类,应该会有其他缓冲区大小分配方案。 现在回到 read 方法中,guess是在 allocate方法中调用的,而 allocate 则是一个RecvByteBufAllocator.Handle类型。
首先调用 config方法,然后调用getRecvByteBufAllocator来创建这个allocHandle。看下 config方法哪来的? 原来是在 Channel 中设置的呀,那既然有getRecvByteBufAllocator方法,那么肯定也有setRecvByteBufAllocator方法,我们在ChannelInitializer 中来调用下setRecvByteBufAllocator方法,并 new 一个FixedRecvByteBufAllocator来替换AdaptiveRecvByteBufAllocator 再次重启 Netty 的 Tcp 服务器,发现每次能够完整的接收到 1026字节,把 maxLen 改成 2056之后也是如此,问题解决! |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |