Для получения IPv4 TCP по крайней мере в Linux, MSG_WAITALL игнорируется, если указан MSG_NONBLOCK (или дескриптор файла установлен на неблокирующее).
Из tcp_recvmsg () в net / ipv4 / tcp.c в ядре Linux:
if (copied >= target && !sk->sk_backlog.tail)
break;
if (copied) {
if (sk->sk_err ||
sk->sk_state == TCP_CLOSE ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
!timeo ||
signal_pending(current))
break;
target в этом приведении установлен на запрошенный размер, если указан MSG_DONTWAIT, или на меньшее значение (по крайней мере 1), если нет. Функция завершится, если:
- Скопировано достаточно байтов
- Ошибка сокета
- Розетка была закрыта или отключена
- timeo равно 0 (для сокета установлено неблокирующее значение)
- Ожидается сигнал для процесса
Мне кажется, что это может быть ошибкой в Linux, но в любом случае это не будет работать так, как вы хотите. Похоже, что решение dec-vt100 будет, но есть условие гонки, если вы пытаетесь получить из одного и того же сокета более чем один процесс или поток.
То есть может произойти другой вызов recv () другим потоком / процессом после того, как ваш поток выполнил просмотр, в результате чего ваш поток заблокировался на втором recv ().