LINUX.ORG.RU

select: реагирует ли на SO_RCVLOWAT и SO_SNDLOWAT?


0

0

В man 7 socket написано следующее:
SO_SNDLOWAT is not changeable on Linux (setsockopt(2) fails with the error
ENOPROTOOPT). SO_RCVLOWAT is changeable only since Linux 2.4. The select(2) and
poll(2) system calls currently do not respect the SO_RCVLOWAT setting on Linux,
and mark a socket readable when even a single byte of data is available. A
subsequent read from the socket will block until SO_RCVLOWAT bytes are
available.

Однако, судя по тестам, которые я не поленился провести, select их таки слушается (рабочий дистр Бубунту 9.04).
Так как оно на самом деле (интересуют современные дистрибутивы/ядра Linux и, если кто с ней сталкивался и знает, ОСРВ Багет)?

★★

Ответ на: комментарий от Chumka

На сервере читаю небольшими порциями (зд. 1 кб):
> char buf[1000];

>

> while(1)

> {

> read(fd, buf, sizeof buf);

> sleep(1);

> }


На клиенте пишу бОльшими (зд. 10кб).
При этом select работает, данные пишутся порциями по 10кб.
> char buf[10000];

> int sock = my_connect("192.168.100.100", MY_PORT);

>

> long flags;

> int socket_lowat = sizeof buf;

>

> flags = fcntl(sock, F_GETFL, 0);

> fcntl(sock, F_SETFL, flags | O_NONBLOCK);

>

> setsockopt(sock, SOL_SOCKET, SO_SNDLOWAT, &socket_lowat, sizeof socket_lowat);

>

> while(1)

> {

> fd_set select_sockets;

> FD_ZERO(&select_sockets);

> FD_SET(sock, &select_sockets);

>

> select(sock + 1, NULL, &select_sockets, NULL, NULL);

> if(write(sock, buf, sizeof buf) != sizeof buf);

> abort();

> }

Привел естественно урезанный код, в оригинале всё параноидально проверяется. Пробовал разные размеры буферов и т.п.
Итог: без селекта валится (см. abort), с селектом все ок.

Tayler ★★
() автор топика
Ответ на: комментарий от Tayler

Я не понимаю, почему из этого кода следует, что select слушается SO_SNDLOWAT.

Эта строчка
setsockopt(sock, SOL_SOCKET, SO_SNDLOWAT, &socket_lowat, sizeof socket_lowat);

возвращает -1 с ошибкой ENOPROTOOPT, о чем и сказано в мане. Следовательно select'у она по барабану.

Chumka ★★★
()
Ответ на: комментарий от Chumka

> Эта строчка
> setsockopt(sock, SOL_SOCKET, SO_SNDLOWAT, &socket_lowat, sizeof socket_lowat);

>

> возвращает -1 с ошибкой ENOPROTOOPT, о чем и сказано в мане.

> Следовательно select'у она по барабану.

В оригинальном (а не урезанном для поста) коде (который на работе сейчас, не могу привести полностью) возвращаемое значение проверялось и функция как раз возвращает ноль!

Tayler ★★
() автор топика
Ответ на: комментарий от Tayler

В исходниках ядра в файле net/core/sock.c SO_SNDLOWAT не обрабатыватеся, во всяком случае для версии 2.6.29.4. Сделайте strace на оригинальный пример.

mky ★★★★★
()
Ответ на: комментарий от mky

Чёрт! пардон, мой косяк (
На ОСРВ-то работает, а на Linux'е нет (как по манам). А жаль.

Tayler ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.