1

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

  1. ReadableByteChannela から aに読み込みByteBuffer
  2. 転送されたバイトを記録し、
  3. 数十から数百ミリ秒休止し、
  4. ByteBufferをに渡しWritableByteChannelます。

いくつかの詳細:

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

問題は、 ByteBuffer がどれだけ大きく割り当てられていても、 または のいずれかで.allocate().allocateDirect()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 を超えています。(これはまた、私が予想していたであろう非常に丸い数ではありません。)

ここで何が問題なのか、私は本当に困惑しています。理論的には、知る限り、これは起こるべきではありません。ストリームベースのソリューションに「ダウングレード」することは望ましくありませんが、ソリューションが見つからない場合は、ストリーム ベースのソリューションに移行します。

私は何が欠けていますか?修正するにはどうすればよいですか?

4

1 に答える 1

0

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

ReadableByteChannelインスタンスから直接Socketインスタンス化するのではなく、HttpEntity.getContent()( Apache HTTP Commons Client ) メソッドのreturnからインスタンス化していましたInputStream。HTTP Commons クライアントには、メソッドを使用して早い段階でソケットが渡されていましたDefaultHttpClientConnection.bind()。私が理解できなかったのは、Channel がBufferedInputStreamHTTP Commons Client 実装内に埋め込まれたインスタンスであるということです。(たまたま Java 6 のデフォルト値は 8KB です。)

したがって、私の解決策はReadableByteChannel、未加工のSocketインスタンスを取得することでした。

于 2010-09-16T12:18:55.290 に答える