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

时间:2013-05-02 14:56:36

标签: java performance sockets networking

我有一个NIO服务器,它获取小客户端请求,导致~1meg响应。服务器使用以下内容接受新客户端:

SocketChannel clientChannel = server.accept();
clientChannel.configureBlocking(false);
clientChannel.socket().setSendBufferSize(2 * 1024 * 1024);

然后我注销了一个“客户端连接”行,其中包含clientChannel.socket()。getSendBufferSize()的结果。

在Windows上,该集将客户端套接字的发送缓冲区大小从8k更改为2megs。但在linux上,套接字表示其发送缓冲区为131,071字节。

这导致糟糕的性能,因为我的clientChannel.write一次只写128k,因此需要多7次传递才能获得所有数据。在Windows上,setSendBufferSize更改显着提高了性能。

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

$ cat /proc/sys/net/ipv4/tcp_wmem
4096    16384   4194304

2 个答案:

答案 0 :(得分:2)

平台可以自由调整请求的缓冲区大小,这就是Linux似乎正在做的事情。除了可以通过内核配置调整最大值之外,你无能为力。

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

我不明白为什么要求“更多通行证”应该导致如此重大的性能差异,甚至是你问这个问题。在我看来,你最好先调整接收器的窗口大小,然后在连接之前按上述方式进行操作。

答案 1 :(得分:-2)

您可以继承ServerSocket,并覆盖ServerSocket.implAccept(Socket socket)。 在您的覆盖中,此方法将收到一个“空”Socket实例,您可以在其上调用Socket.setSendBufferSize(int)

然后:

ServerSocketChannel server = myServerSocket.getChannel();
...
SocketChannel clientChannel = server.accept();  // <-- this guy will have the new send buffer size.