Является ли sockets accept () возвращающим дескриптор блокирующим или неблокирующим?

#c #sockets

#c #сокеты

Вопрос:

Возвращается ли дескриптор сокета accept() функцией в блокирующем или неблокирующем режиме?

Ответ №1:

От man 2 accept :

    int accept4(int sockfd, struct sockaddr *addr,
               socklen_t *addrlen, int flags);
  

И далее вниз:

    If flags is 0, then accept4() is the same as accept().   The  following
   values can be bitwise ORed in flags to obtain different behavior:

   SOCK_NONBLOCK   Set  the  O_NONBLOCK  file  status flag on the new open
                   file description.  Using this flag saves extra calls to
                   fcntl(2) to achieve the same result.
  

Таким образом, я ожидал бы, что дескриптор сокета, возвращаемый из accept (), будет находиться в режиме блокировки.

Ответ №2:

Нет, сокеты не наследуют неблокирующий статус от прослушивающего сокета. Вы должны сделать это неблокирующим самостоятельно.

Комментарии:

1. Согласно MSDN: «Вновь созданный сокет — это сокет, который будет обрабатывать фактическое соединение и имеет те же свойства, что и сокет s , включая асинхронные события, зарегистрированные с помощью WSAEventSelect функции», где s — прослушивающий сокет.

2. @RemyLebeau-TeamB Да, но в нем явно не упоминается статус неблокирующего, поэтому я бы все равно сделал новый принятый неблокирующий socking, чтобы быть в безопасности.

3. @RemyLebeau Я вспоминаю из моего чтения Unix Network Programming vol.1, что сокет наследует свойства сокета , но не свойства на уровне файлового дескриптора.

Ответ №3:

Windows передаст неблокирующее свойство возвращаемому сокету

Linux этого не сделает, вам нужно явно установить сокет в неблокирующее положение (самый простой способ — вызвать accept4 с флагом неблокируемости)

Ответ №4:

Из accept(2):

В Linux новый сокет, возвращаемый accept(), не наследует флаги состояния файла, такие как O_NONBLOCK и O_ASYNC, от прослушивающего сокета. Это поведение отличается от канонической реализации сокетов BSD. Переносимые программы не должны полагаться на наследование или ненаследование флагов состояния файла и всегда явно устанавливают все требуемые флаги на сокет, возвращаемый из accept().

Итак, кажется, что Linux является лишним. BSD и Windows, похоже, наследуют неблокирующее поведение.