Что может вызвать сообщение «Ресурс временно недоступен» в команде sock send ()

85

Что может вызвать Resource temporarily unavailableошибку в send()команде сокета ? Сокет настроен как AF_UNIX, SOCK_STREAM. В большинстве случаев это работает, но иногда возникает эта ошибка. Принимающий конец розетки работает правильно.

Я знаю, что это не очень подробно, но я просто ищу общие идеи. Благодаря!

Giroy
источник
Это связано? stackoverflow.com/questions/5737493/…
падди
4
Вы устанавливаете сокет на O_NONBLOCK?
Deepankar Bajpeyi
Я не думаю, что это связано с тем постом. Мои сокеты - это SOCK_STREAM, которые, как я считаю, блокируют, чего я и хочу.
giroy
3
Блокирующий или неблокирующий поток не зависит от того, SOCK_STREAM или SOCK_DGRAM. Ответ там уместен.
Barmar

Ответы:

96

"Resource temporarily unavailable"- сообщение об ошибке, соответствующее значку EAGAIN, что означает, что операция была бы заблокирована, но была запрошена неблокирующая операция. Ибо send()это может быть связано с одним из следующих факторов:

  • явная пометка файлового дескриптора как неблокирующего с помощью fcntl(); или же
  • передача MSG_DONTWAITфлага send(); или же
  • установка тайм-аута отправки с помощью SO_SNDTIMEOпараметра сокета.
кафе
источник
Причина моей проблемы заключалась в установке тайм-аута отправки. Спасибо за помощь!
giroy
@caf, В моем случае разная конфигурация размера MTU на двух сторонах приводила к переполнению Txqueue ассоциации sctp, когда происходила высокая скорость обмена пакетами. Сделав одинаковый MTU в обеих системах, проблема исчезла. Но может ли кто-нибудь объяснить, в чем причина проблемы?
Codename_DJ
46

Это потому, что вы используете non-blockingсокет, а выходной буфер заполнен.

Со send()страницы руководства

EAGAIN - это код ошибки, привязанный к "Ресурс временно недоступен"

Рассмотрите возможность использования, select()чтобы лучше контролировать это поведение

Давиде Берра
источник
@giroy: но не совсем верно ... на самом деле блокирующий сокет, сSO_SNDTIMEO
EML
Круто, но как мы можем использовать другое соединение для управления одновременным чтением в БД?
MUY Belgium
10

Приведу пример:

  1. клиент подключается к серверу и отправляет на сервер 1 МБ данных каждые 1 секунду.

  2. сторона сервера принимает соединение, а затем спит 20 секунд, без сообщения recv от клиента. Таким образом, tcp send bufferна стороне клиента будет заполнено.

Код на стороне клиента:

Код на стороне сервера:

Запустить на стороне сервера, затем запустить на стороне клиента.

сторона сервера может выводить:

введите описание изображения здесь

сторона клиента может выводить:

введите описание изображения здесь

Вы можете видеть, как серверная сторона не получает данные от клиента, поэтому, когда клиентская сторона tcp bufferзаполняется, вы все равно отправляете данные, поэтому вы можете получить Resource temporarily unavailableошибку.

Джейхелло
источник