我有一些代码:
- 从 a 读
ReadableByteChannel
入 aByteBuffer
, - 记下传输的字节,
- 暂停几十到几百毫秒,
- 传递
ByteBuffer
到 a 上WritableByteChannel
。
一些细节:
- 两个通道都是 TCP/IP 套接字。
- 总连接读取大小为数十兆字节。
- 源套接字(从中
ReadableByteChannel
获取字节)在同一台机器上。 - HP DL380s 上的 Debian Lenny 64 位
- Sun Java 1.6.0 更新 20
问题是,无论分配多大的 ByteBuffer,使用.allocate()
或.allocateDirect()
,读入 ByteBuffer 的字节数最大为 8KB。我的目标 ByteBuffer 大小是 256KB,这只是一小部分(1/32nd)被使用。大约 10% 的时间只读入 2896 个字节。
我检查了操作系统 TCP 缓冲区设置,它们看起来不错。观察 netstat 关于缓冲区中有多少字节的报告证实了这一点——两者的套接字缓冲区中的数据都超过了 8KB。
tcp 0 192384 1.2.3.4:8088 1.2.3.4:53404 ESTABLISHED
tcp6 110144 0 1.2.3.4:53404 1.2.3.4:8088 ESTABLISHED
这里突出的一件事是 TCP 和 TCP6 的混合,但我认为这应该不是问题。在上面的输出中,我的 Java 客户端位于端口 53404 上。
我尝试设置套接字属性以支持带宽而不是延迟,但没有改变。
Socket socket = new Socket(host.getHostName(), host.getPort());
socket.setPerformancePreferences(1, 0, 2); //bw > connection time > latency
当我记录 的值时socket.getReceiveBufferSize()
,它始终只报告 43856 个字节。虽然它比我想要的要小,但它仍然超过 8KB。(这也不是一个非常整数,这是我所预料的。)
我真的很困惑这里有什么问题。理论上,AFAIK,这不应该发生。“降级”到基于流的解决方案是不可取的,尽管如果找不到解决方案,这就是我们接下来要去的地方。
我错过了什么?我能做些什么来纠正它?