Java7 DatagramSocket.setReceiveBufferSize е различен между Windows и Linux?

извиквайки този код както на Linux (Ubuntu 12.04), така и на Windows 7, получавате много различни резултати:

DatagramSocket socket = new DatagramSocket(4445);
socket.setReceiveBufferSize(Integer.MAX_VALUE);
System.out.println("SO_RX_BUFFER SET TO:"+socket.getReceiveBufferSize());

Linux получавате: SO_RX_BUFFER SET TO:131071

и под Windows получавате: SO_RX_BUFFER SET TO:2147483647

Защо драстичната разлика между операционните системи? Защо толкова малка стойност за linux? Има ли все пак размерът на буфера на Linux да се увеличи?


person Ryan R.    schedule 19.10.2012    source източник


Отговори (2)


Това, което се случва тук е, че хост операционните системи се държат по различен начин.

  • В случая с Linux операционната система поставя горна граница на това, което можете да поискате от дадено приложение. За да разрешите това, ще трябва да промените настройките за конфигурация на операционната система. Това ще изисква "root" привилегия и не трябва да се прави от приложение.

    Тази страница съдържа основна информация за мрежовата настройка на Linux.

  • В случая с Windows операционната система или не поставя ограничение, или (по-вероятно) тихо отменя заявения от потребителя размер на буфера, ако той е по-голям от ограничението, наложено от операционната система.


Като казахте това, трябва да помислите какво правите тук. Буферираните мрежови пакети (RX и TX) най-вероятно трябва да се съхраняват във физическа памет. Когато увеличите ограниченията, вие принуждавате операционната система да запази повече RAM страници за себе си, намалявайки наличната памет за нормални приложения.

Вторият проблем е, че увеличаването на обема на мрежовото буфериране може да бъде вредно, ако основният проблем е, че приложението ви трудно поддържа темпото. В най-лошия случай вашето приложение непрекъснато ще обработва стари пакети, като новите пакети ще бъдат отхвърлени. Накратко, допълнителното буфериране влошава латентността, без (непременно) да елиминира загубата на данни.

person Stephen C    schedule 20.10.2012

Изглежда, че това е дубликат: Защо промяната на стойността на SO_RCVBUF не работи ?

Изглежда, че Linux има ограничение за конфигурационни файлове.

Добавяне на следното:

net.core.rmem_max = 16777216 (или каквото искате да бъде вашият лимит)

към /etc/sysctl.conf

разреши проблема.

person Ryan R.    schedule 20.10.2012
comment
Това е нещо като същия проблем, както се гледа от java. - person Ryan R.; 20.10.2012