Java 在linux上设置套接字发送缓冲区大小的正确方法?

Java 在linux上设置套接字发送缓冲区大小的正确方法?,java,performance,sockets,networking,Java,Performance,Sockets,Networking,我有一个NIO服务器,它获取小客户机请求,从而产生约1meg响应。服务器使用以下各项接受新客户端: SocketChannel clientChannel = server.accept(); clientChannel.configureBlocking(false); clientChannel.socket().setSendBufferSize(2 * 1024 * 1024); 然后,我注销一个“客户端连接”行,其中包含clientChannel.socket().getSendBu

我有一个NIO服务器,它获取小客户机请求,从而产生约1meg响应。服务器使用以下各项接受新客户端:

SocketChannel clientChannel = server.accept();
clientChannel.configureBlocking(false);
clientChannel.socket().setSendBufferSize(2 * 1024 * 1024);
然后,我注销一个“客户端连接”行,其中包含clientChannel.socket().getSendBufferSize()的结果

在Windows上,该集合将客户端套接字的发送缓冲区大小从8k更改为2MEG。但是在linux上,套接字说它的发送缓冲区是131071字节

这会导致糟糕的性能,因为我的clientChannel.write一次只写入128k,所以需要再进行7次才能写入所有数据。在Windows上,setSendBufferSize更改显著提高了性能

Linux似乎已配置为允许使用大型套接字发送缓冲区:

$ cat /proc/sys/net/ipv4/tcp_wmem
4096    16384   4194304
您可以创建子类并重写。 在重写中,此方法将接收一个“空”实例,您可以对其调用

然后:

serversocketchannelserver=myServerSocket.getChannel();
...

SocketChannel clientChannel=server.accept();// 平台可以自由地向上或向下调整请求的缓冲区大小,而Linux似乎就是这么做的。除了可能通过内核配置来调整maxima之外,您对此无能为力

请注意,我在您链接的关于设置缓冲区大小>64k的问题中的评论适用于接收缓冲区,而不是发送缓冲区,因为接收缓冲区大小会影响窗口缩放选项,因此需要在连接套接字之前进行设置,这会将窗口比例设置为零


我不明白为什么要求“更多的传球”会导致如此大的性能差异,以至于你甚至会问这个问题。在我看来,您最好向上调整接收器的窗口大小,并在连接之前按上述步骤进行操作。

此问题表示我需要在调用accept之前设置SendBufferSize:。但是在我调用accept之前,我没有clientChannel。我对这个问题的评论是关于接收缓冲区大小的。您可以随时设置发送缓冲区大小。子类化ServerSocket对ServerSocketChannel没有影响,并且整个操作在设置发送缓冲区大小时没有任何区别。增加客户端的接收缓冲区在Windows客户端上起作用,但不会导致服务器增加其发送缓冲区。当服务器有1meg要发送且只有128k发送缓冲区时,需要再调用7个clientChannel.write才能发送所有数据。我应该继续在一个循环中调用write吗?增加接收方的接收缓冲区对服务器的发送缓冲区没有影响,也没有其他的说法。如果您处于阻塞模式,一次写入就可以了,否则您必须循环。看来net.core.wmem_max将我限制在128k。按照上的说明,我的Java程序可以请求2meg发送缓冲区。
ServerSocketChannel server = myServerSocket.getChannel();
...
SocketChannel clientChannel = server.accept();  // <-- this guy will have the new send buffer size.