поведение сокета в режиме блокировки - PullRequest
1 голос
/ 19 марта 2009

Меня интересует поведение функции отправки при использовании блокирующего сокета .

Руководство явно указывает ничего об этом случае.

Из моих тестов (и документации) получается, что при использовании send на блокирующем сокете у меня есть 2 случая:

  • все данные отправлены
  • возвращается ошибка и ничего не отправляется

В строках кода (например, в C) это переводится так:

    // everything is allocated and initilized
    int socket_fd;
    char *buffer; 
    size_t buffer_len;
    ssize_t nret;

    nret = send(socket_fd, buffer, buffer_len, 0);
    if(nret < 0)
    {
          // error - nothing was sent (at least we cannot assume anything)
    }
    else
    {
          // in case of blocking socket everything is sent (buffer_len == nret)
    }

Я прав?

Меня интересует такое поведение на всех платформах (Windows, Linux, * nix).

Ответы [ 2 ]

1 голос
/ 20 марта 2009

Насколько я понимаю, блокирующая отправка не обязательно должна быть атомарной, см., Например, страницу руководства Solaris send :

For socket types such as SOCK_DGRAM and SOCK_RAW that require atomic messages,
the error EMSGSIZE is returned and the message is not transmitted when it is
too long to pass atomically through the underlying protocol. The same
restrictions do not apply to SOCK_STREAM sockets.

А также посмотрите на код ошибки EINTR:

The operation was interrupted by delivery of a signal before any data could
be buffered to be sent.

Это означает, что отправка может быть прервана после того, как некоторые данные были буферизированы для отправки, но в этом случае send вернет количество байтов, которые уже были буферизованы для отправки (вместо кода ошибки EINTR). *

На практике я ожидал бы увидеть такое поведение только для больших сообщений (которые не могут быть обработаны атомарно атомной системой) в сокетах SOCK_STREAM.

1 голос
/ 19 марта 2009

со страницы руководства. (http://linux.die.net/man/2/send)

"В случае успеха эти вызовы возвращают количество отправленных символов. В случае ошибки возвращается -1 и значение errno устанавливается соответствующим образом."

У вас есть три условия.

  • -1 - локальная ошибка в сокете или его привязке.

  • Некоторое число <длина: не все байты были отправлены. Это обычно тот случай, когда сокет помечается как неблокирующий, а запрошенная операция блокируется; ошибочное значение EAGAIN. </p>

    Возможно, вы этого не увидите, потому что блокируете ввод / вывод.

    Однако другой конец розетки может преждевременно закрыть соединение, что может привести к этому. Значение errno, вероятно, будет EPIPE.

  • Некоторое число == длина: все байты были отправлены.

...