先说说事件回放
某天客户端要求说tcp包要小点,这样他开的buffer就小点
那我就找到acceptor.getSessionConfig().setSendBufferSize(int);这个方法设置发送byte buffer的大小,但我把他设置成1,让他每个包都即时发送
mina的setSendBufferSize方法是一个接口,他会调用java.net.Socket.setSendBufferSize文件
jdk的描述是这样的
由于 SO_SNDBUF 是一种提示,想要验证缓冲区设置大小的应用程序应该调用 getSendBufferSize()。
意思就是发送buffer吧
用工具在客户端捉包的结果显示最大包 还是1460,但tcp包id的数量不同了
举个例子:
SendBufferSize为1024时(15:55:45.225中的225就是包id号)捉取的数据包如下
时间(.包id) 包长 数据长度 具体数据
15:55:45.225 63 9 xxxxxxxx(具体数据)
15:55:45.225 63 19 xxxxxxxx(具体数据)
15:55:45.225 63 39 xxxxxxxx(具体数据)
15:55:45.225 63 932 xxxxxxxx(具体数据)
15:55:47.225 63 93 xxxxxxxx(具体数据)
15:55:47.225 63 9 xxxxxxxx(具体数据)
15:55:47.225 63 9 xxxxxxxx(具体数据)
SendBufferSize为1时(15:55:45.225中的22X就是包id号)捉取的数据包如下
时间(.包id) 包长 数据长度 具体数据
15:55:45.225 63 9 xxxxxxxx(具体数据)
15:55:45.225 63 19 xxxxxxxx(具体数据)
15:55:45.226 63 39 xxxxxxxx(具体数据)
15:55:45.227 63 932 xxxxxxxx(具体数据)
15:55:47.228 63 93 xxxxxxxx(具体数据)
15:55:47.229 63 9 xxxxxxxx(具体数据)
15:55:47.230 63 9 xxxxxxxx(具体数据)
可以明显看出当SendBufferSize 1时,tcp包发送非常及时(基本上没有做buffer >.<)
这个时候问题鬼异的问题就来了
先来看看现象
服务器发送一个超过2920数据长度的包
mina代码约为这样
IoBuffer buffer = ba.allocate(3320, false);
buffer.flip();
session.write(buffer);
网卡底层tcp包就会分成三个发
数据大小分别是1460 1460 400
测试
内网服务器为linux 时就会丢了最后一个包即长度为400的包(5,5.2,5.3都是这样)
windows和ubuntu没有问题,这个时候奇怪的问题又来了,我们的外网linux服务器没有问题(ps 内网和外网服务器的linux版本是一样的,还是同一长碟,但硬件不一样)
真NN的奇怪,为什么只有内网的linux才会这样,外网的就不会呢,,为什么windows,和ubuntu就不会有这个问题??????
最后我们把setSendBufferSize设回为1024就没有这个问题了
来源:oschina
链接:https://my.oschina.net/u/16/blog/3356