ReadableByTechannel.Read(bytebuffer dest)8kbでキャップされた読み取り。なんで?

StackOverflow https://stackoverflow.com/questions/3718464

質問

私はいくつかのコードを持っています:

  1. aから読みます ReadableByteChannelByteBuffer,
  2. 転送されたバイトに注意してください、
  3. 数十から数百のミリ秒を一時停止し、
  4. に合格します ByteBufferWritableByteChannel.

いくつかの詳細:

  • 両方のチャネルはTCP/IPソケットです。
  • 合計接続読み取りサイズは、数十メガバイトです。
  • ソースソケット( ReadableByteChannel からバイトを取得しています)は同じマシンにあります。
  • HP DL380SのDebian Lenny 64ビット
  • Sun Java 1.6.0アップデート20

問題は、どんなに大きくても、bytebufferが割り当てられていても、 .allocate() また .allocateDirect(), 、8kbでBytebuffer Maxesに読み取られるバイト数。私のターゲット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

ここで際立っていることの1つは、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、これは起こってはいけません。ストリームベースのソリューションに「ダウングレード」することは望ましくありませんが、ソリューションが見つからない場合は次に進む場所です。

何が足りないの?それを修正するために私は何ができますか?

役に立ちましたか?

解決

わかりました、私は問題を見つけました! (そして、誰かが同じ問題を抱えている場合に備えて、私自身の質問に答えています。)

私はインストールしていました ReadableByteChannel 直接からではありません Socket インスタンスですが、 HttpEntity.getContent() (Apache HTTP Commonsクライアント)メソッドが返されました InputStream. 。 HTTP Commonsクライアントは、早い段階でソケットに渡されていました DefaultHttpClientConnection.bind() 方法。私が理解していなかったのは、チャンネルは BufferedInputStream HTTP Commonsクライアントの実装内に埋もれたインスタンス。 (8kbはたまたまJava 6のデフォルト値です。)

したがって、私の解決策は、をつかむことでした ReadableByteChannel 生のオフ Socket 実例。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top