[freebsd] socket

15 views
Skip to first unread message

Nick Kostirya via freebsd

unread,
Apr 21, 2021, 12:39:25 PM4/21/21
to fre...@uafug.org.ua
Привет.

Вопрос по сокетам.

Забыл открыть сокет в неблокирующем режиме.
После select записывалось столько данных, сколько влезало, и операция записи не блокировалась.

А вот при запуске под Линуксом обнаружил эту ошибку, так как там запись блокируется.

Это такая особенность FreeBSD или всех BSD?
А как под Солярисом?
_______________________________________________
freebsd mailing list
fre...@uafug.org.ua
http://mailman.uafug.org.ua/mailman/listinfo/freebsd

Valentin Nechayev

unread,
Apr 21, 2021, 2:00:35 PM4/21/21
to Nick Kostirya, fre...@uafug.org.ua
hi,

Wed, Apr 21, 2021 at 19:39:14, freebsd wrote about "[freebsd] socket":

> Забыл открыть сокет в неблокирующем режиме.
> После select записывалось столько данных, сколько влезало, и операция записи не блокировалась.
>
> А вот при запуске под Линуксом обнаружил эту ошибку, так как там запись блокируется.
>
> Это такая особенность FreeBSD или всех BSD?

Вообще-то все send() должны блокироваться, если не могут за раз
отправить все данные в ядерный буфер, и если nonblocking не выставлено
(включая MSG_DONTWAIT в опциях sendto/sendmsg).

Может, под FreeBSD этот буфер оказался больше?


-netch-

Eugene Grosbein

unread,
Apr 21, 2021, 6:21:51 PM4/21/21
to Nick Kostirya, fre...@uafug.org.ua
21.04.2021 23:39, Nick Kostirya via freebsd пишет:

> Привет.
>
> Вопрос по сокетам.
>
> Забыл открыть сокет в неблокирующем режиме.
> После select записывалось столько данных, сколько влезало, и операция записи не блокировалась.
>
> А вот при запуске под Линуксом обнаружил эту ошибку, так как там запись блокируется.
>
> Это такая особенность FreeBSD или всех BSD?
> А как под Солярисом?

И то, и другое - допустимое поведение системы.

Из man send:

If no messages space is available at the socket to hold the message to be
transmitted, then send() normally blocks.

Из man setsockopt:

SO_SNDLOWAT is an option to set the minimum count for output operations.
Most output operations process all of the data supplied by the call,
delivering data to the protocol for transmission and blocking as
necessary for flow control. Nonblocking output operations will process
as much data as permitted subject to flow control without blocking, but
will process no data if flow control does not allow the smaller of the
low water mark value or the entire request to be processed. A select(2)
operation testing the ability to write to a socket will return true only
if the low water mark amount could be processed. The default value for
SO_SNDLOWAT is set to a convenient size for network efficiency, often
1024.

На FreeBSD давно есть автомасштабирование буфера сокета, принимающего данные
для отправки ядром без синхронизации приложения. Дефолтный размер значения
sysctl net.inet.tcp.sendspace=32K для приложений,
которые сами не меняет дефолты при помощи setsockopt, автоувеличение включено
порциями по net.inet.tcp.sendbuf_inc=8K вплоть до 8M.

Условия автоувеличения буфера описаны в sys/netinet/tcp_output.c
в комментариях функции tcp_sndbuf_autoscale() (FreeBSD 12+) или tcp_output (FreeBSD 11 и ранее).

А в FreeBSD 12 и новее ещё есть sysctl net.inet.tcp.sendbuf_auto_lowat (выключено по дефолту),
при включенном процедура автоувеличения буфера принимает во внимание пользовательское
значение SO_SNDLOWAT: https://reviews.freebsd.org/D11016

Nick Kostirya via freebsd

unread,
Apr 21, 2021, 9:58:11 PM4/21/21
to fre...@uafug.org.ua
On Wed, 21 Apr 2021 19:39:14 +0300
Nick Kostirya via freebsd <fre...@uafug.org.ua> wrote:

> Привет.
>
> Вопрос по сокетам.
>
> Забыл открыть сокет в неблокирующем режиме.
> После select записывалось столько данных, сколько влезало, и операция записи не блокировалась.
>
> А вот при запуске под Линуксом обнаружил эту ошибку, так как там запись блокируется.
>
> Это такая особенность FreeBSD или всех BSD?
> А как под Солярисом?

Ой.
Сокеты наследуют неблокирующий режим от accept. Так что они работают в неблокирующем режиме.
А вот под Linux не наследуется.

Порылся в своих записях: оказывается давным давно уже сталкивался с этим. :-)

Спасибо.

Reply all
Reply to author
Forward
0 new messages