Для 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().
person
Matt
schedule
11.06.2013