我正在编写一些java TCP / IP网络代码(客户端 - 服务器),其中我必须处理发送比接收快得多的情况,从而阻止一端的发送操作。 (因为send和recv缓冲区已填满)。为了设计我的代码,我想首先围绕这些情况,看看客户端和服务器在不同负载下的行为。但是我无法适当地设置参数来实现这种背压。我尝试将Socket.setSendBufferSize(int size)
和Socket.setReceiveBufferSize(int size)
设置为较小的值 - 希望尽快填满,但我可以看到发送操作完成而无需等待客户端消耗已写入的足够数据。 (这意味着小的send和recv缓冲区大小没有影响)
我采用的另一种方法是使用Netty,然后设置ServerBootstrap.setOption("child.sendBufferSize", 256);
,但即使这样也没用多少。任何人都可以帮助我理解我做错了什么/
答案 0 :(得分:4)
我认为Channel.setReadable
就是你所需要的。 setReadable告诉netty临时暂停从缓冲区中的系统套接字读取数据,当缓冲区已满时,另一端必须等待。
答案 1 :(得分:3)
缓冲区具有依赖于操作系统的最小值,通常大约为8 KB。
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.
这是发送和接收缓冲区的总和,但我怀疑它们都是16 KB