chandrAN2& Ответов: 1

О сокете rmem_max и wmem_max


У меня есть следующее сомнение, связанное с сокетами rmem_max и wmem_max.
Ниже приведен вывод, взятый с моей linux-машины.

cat /proc/sys/net/core/rmem_max
212992
cat /proc/sys/net/core/rmem_default
212992
cat /proc/sys/net/core/wmem_max
212992
cat /proc/sys/net/core/wmem_default
212992.

поэтому я подумал о том, чтобы проверить, действительно ли вышеприведенные значения работают так, как ожидалось, или нет. Я создал два процесса (клиентский сокет и серверный сокет), оба являются локальными Unix-сокетами(AF_UNIX). Я заставил серверную программу спать в течение неопределенного периода времени, прежде чем вызов recv() был выполнен.

Клиентский сокет отправляет 1024 байта в серверный сокет в непрерывном цикле while.
Но я не получаю ошибку даже после отправки более 212992 байт. Насколько я понимаю, поскольку сервер спит неопределенно долго, он не сможет получить данные из буфера сокета ядра в то же время, когда клиент продолжает передавать данные на сервер. Таким образом, все эти данные будут храниться в буфере ядра. с отправить() имеет ограничение 212992 байт(wmem_max) , отправить() клиента вызов не выполняется, после достаточного буфера ядра использовался.

Но этого не происходит, я мог видеть, что более 113271663 числа ietrations продолжаются без каких-либо проблем, и вызов send() вовсе не терпит неудачу.

Что означает значение wmem_default и rmem_default?


Может ли кто-нибудь уточнить, каковы максимальные буферы сокетов, доступные в linux для send() и recv (), и как эти огромные данные хранятся в буферах сокетов ядра linux без каких-либо сбоев?

Что я уже пробовал:

Успешно отправлено 1024 байта (i=139453022)
Успешно отправлено 1024 байта (i=139453023)
Успешно отправлено 1024 байта (i=139453024)
Успешно отправлено 1024 байта (i=139453025)
Успешно отправлено 1024 байта (i=139453026)
Успешно отправлено 1024 байта (i=139453027)
...

139453027 количество 1024 фрагментов было отправлено через вызов ядра send () без каких-либо сбоев.


// ниже приведена серверная программа, Спящая неопределенно долго

для(;;) {
int завершено, n, num;
printf ("ожидание соединения ... \n");
n = sizeof (удаленный);
если ((sock_serv = принять(носок, (структура структуры *)&усилителя;дистанционный, &амп;Н)) == -1) {
perror ("принять вызов не удалось");
выход(1);
}

printf ("серверный сокет подключен.\n");
сон(100000); // бессрочный сон
завершено = 0;
делать {
num = recv(sock_serv, str, 1024, 0);
;
;
;
}

KarstenK

долгий сон - это всегда плохая идея, потому что весь поток находится в спящем режиме.
Лучше опрашивать каждые 100 мс. Это долгое время в циклах процессора.

1 Ответов

Рейтинг:
2

Albert Holguin

Это интересное поведение, если мне нужно было догадаться, это тот факт, что вы используете локальный сокет AF_UNIX, который видит это поведение. Когда вы указываете" локальный " сокет, ядро обрабатывает его совершенно по-другому. Локальные сокеты-это, по сути, просто системные файлы, потому что это более эффективно, поэтому размер файла не может быть ограничен точно таким же образом.

Я предполагаю, что если бы вы использовали настоящие сокеты AF_INET, вы бы начали видеть повторные передачи/потерянные/отброшенные пакеты.