7

私はいくつかのJavaTCP/ IPネットワークコード(クライアント-サーバー)を書いています。このコードでは、送信が受信よりもはるかに高速であるため、一方の端で送信操作がブロックされるシナリオに対処する必要があります。(sendおよびrecvバッファーがいっぱいになるため)。コードを設計するために、最初にこのような状況を試して、さまざまな負荷の下でクライアントとサーバーがどのように動作するかを確認したいと思いました。しかし、この背圧を達成するためのパラメータを適切に設定することはできません。値を小さく設定Socket.setSendBufferSize(int size)してみSocket.setReceiveBufferSize(int size)ましたが、すぐにいっぱいになることを期待していますが、クライアントが既に書き込まれたデータを十分に消費するのを待たずに、送信操作が完了することがわかります。(これは、sendおよびrecvのバッファサイズが小さいと効果がないことを意味します)

私が取ったもう1つのアプローチは、Nettyを使用して設定することServerBootstrap.setOption("child.sendBufferSize", 256);ですが、これでもあまり役に立ちません。誰かが私が間違っていることを理解するのを手伝ってくれますか/

4

2 に答える 2

4

Channel.setReadableはあなたが必要なものだと思います。setReadableは、バッファ内のシステムソケットからデータを読み取るようにnettyの一時的な一時停止を指示します。バッファがいっぱいになると、もう一方の端は待機する必要があります。

于 2012-04-04T17:24:07.097 に答える
4

バッファの最小サイズはOSに依存しますが、これは多くの場合約8KBです。

public static void main(String... args) throws IOException, InterruptedException {
    ServerSocketChannel ssc = ServerSocketChannel.open();
    ssc.bind(new InetSocketAddress(0)); // open on a random port
    InetSocketAddress remote = new InetSocketAddress("localhost", ssc.socket().getLocalPort());
    SocketChannel sc = SocketChannel.open(remote);
    configure(sc);
    SocketChannel accept = ssc.accept();
    configure(accept);

    ByteBuffer bb = ByteBuffer.allocateDirect(16 * 1024 * 1024);
    // write as much as you can
    while (sc.write(bb) > 0)
        Thread.sleep(1);
    System.out.println("The socket write wrote " + bb.position() + " bytes.");
}

private static void configure(SocketChannel socketChannel) throws IOException {
    socketChannel.configureBlocking(false);
    socketChannel.socket().setSendBufferSize(8);
    socketChannel.socket().setReceiveBufferSize(8);
}

私のマシンでプリント

The socket write wrote 32768 bytes.

これは送信バッファと受信バッファの合計ですが、どちらも16KBだと思います

于 2012-04-04T17:24:37.753 に答える