【发布时间】:2011-04-12 17:16:14
【问题描述】:
我有一些代码:
- 从
ReadableByteChannel读取到ByteBuffer, - 记录传输的字节,
- 暂停几十到几百毫秒,
- 将
ByteBuffer传递给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,这不应该发生。 “降级”到基于流的解决方案是不可取的,尽管如果找不到解决方案,我们下一步就是这样做。
我错过了什么?我能做些什么来纠正它?
【问题讨论】:
标签: java sockets channel bytebuffer