我有一些代码:
ReadableByteChannel
读取到ByteBuffer
,ByteBuffer
传递给WritableByteChannel
。 一些细节:
ReadableByteChannel
从中获取字节)在同一台机器上。问题是,无论使用.allocate()
还是.allocateDirect()
分配ByteBuffer有多大,读入ByteBuffer的字节数最大为8KB。我的目标ByteBuffer大小是256KB,这只是使用的一小部分(1/32)。大约10%的时间只读入2896个字节。
我已经检查了OS 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,这不应该发生。将“降级”降级为基于流的解决方案是不可取的,尽管如果找不到解决方案,这就是我们下一步的目标。
我错过了什么?我该怎么做才能纠正它?
答案 0 :(得分:0)
好的,我发现了这个问题! (如果有人遇到同样的问题,我会回答我自己的问题。)
我不是直接从ReadableByteChannel
实例实例化Socket
,而是从HttpEntity.getContent()
(Apache HTTP Commons Client)方法返回InputStream
。 HTTP Commons客户端早期已使用DefaultHttpClientConnection.bind()
方法传递了套接字。我不明白的是,我认为,Channel是一个隐藏在HTTP Commons Client实现中的BufferedInputStream
实例。 (8KB恰好是Java 6的默认值。)
因此,我的解决方案是从原始ReadableByteChannel
实例中获取Socket
。