2013-05-02 5 views
1

У меня есть сервер NIO, который получает небольшие клиентские запросы, которые приводят к ответам ~ 1 мг. Сервер использует следующее принять новый клиент:.Правильный способ установки размера буфера отправки сокетов на linux?

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 
+0

Этот вопрос говорит, что мне нужно установить SendBufferSize перед тем, как принять accept: http://stackoverflow.com/questions/12749174/can-i-increase-the-socket-send-buffer-size-if-the-send- терпит неудачу из-за-к буферу-полной. Но у меня нет clientChannel, пока я не позвоню. –

+0

Мои комментарии к этому вопросу относятся к размеру буфера приема. Вы можете установить размер буфера отправки в любое удобное для вас время. – EJP

ответ

1

Платформа волен настроить требуемый размер буфера вверх или вниз, и это то, что кажется Linux делать. Вы ничего не можете с этим поделать, кроме, может быть, настроить максимумы через конфигурацию ядра.

Обратите внимание, что мои комментарии в вопросе о настройке размера буфера> 64k применяются к буферу приема, а не к буферу отправки, поскольку размер буфера приема влияет на параметр масштабирования окна, поэтому его необходимо установить перед сокетом подключен, который устанавливает шкалу окна в камне.

Я не понимаю, почему требование «больше проходов» должно вызывать такое существенное различие в производительности, что вы даже задаете этот вопрос. Мне кажется, вам лучше настроить размер окна получателя вверх и сделать это до подключения, как указано выше.

+0

Увеличение буфера приема клиента работало на клиенте Windows, но это не приводило к тому, что сервер увеличивал свой буфер отправки. Когда сервер имеет 1meg для отправки и только имеет буфер отправки 128k, он получает еще 7 запросов clientChannel.write, чтобы получить все отправленные данные. Должен ли я продолжать писать в цикле? –

+0

Увеличение буфера приема получателя не влияет на буфер отправки сервера, и нигде он не говорит об обратном. Если вы находитесь в режиме блокировки, будет выполняться одна запись, иначе вам придется перебирать петлю. – EJP

+0

Похоже, что net.core.wmem_max ограничивал меня до 128k. Следуя инструкциям на http://www.cyberciti.biz/faq/linux-tcp-tuning/, моя программа Java запросила буфер отправки 2meg. –

-1

Вы можете создать подкласс 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. 
+0

Subclassing ServerSocket не влияет на ServerSocketChannel, и весь маневр не имеет никакого значения при настройке размера буфера отправки. – EJP

Смежные вопросы