Что означает блокировка в параметре setsockopt SO_RCVTIMEO

Когда я взглянул на setsockopt из MSDN ссылки. я наткнулся на параметр SO_RCVTIMEO, его описание: "Устанавливает время ожидания в миллисекундах для блокировки входящих вызовов." Я думал, что операция прослушивания сокета управляется событиями, что означает, что когда ядро ​​очищает кадр от карты NIC, оно уведомляет мой программный сокет, так что это блокировка все о?

2 ответа

Решение

Функции recv и WSARecv блокируются. Они не управляются событиями (по крайней мере, не на уровне вызова). Даже когда блокировка имеет тайм-аут (как установлено с SO_RECTIMEO опция), они не управляются событиями в том, что касается вашего кода. В этом случае они являются просто псевдоблокирующими (возможно, неблокирующими в зависимости от того, насколько коротким является время ожидания).

Когда вы вызываете WSARecv, он будет ждать, пока данные не будут готовы для чтения. Пока данные не готовы для чтения, они просто ждут. Вот почему это считается блокированием.


Вы правы в том, что по своей сути сетевое взаимодействие обусловлено событиями. Под капотом компьютеры по своей природе управляются событиями. Так работает аппаратная часть. Аппаратные прерывания по сути являются событиями. Вы правы, что на низком уровне происходит то, что ваша сетевая карта сообщает ОС, что она готова к чтению. На этом уровне это действительно событие.

Проблема в том, что WSARecv ждет этого события.


Вот, надеюсь, ясная аналогия. Представьте, что вы по какой-то причине не можете покинуть свой дом. Теперь представьте, что ваш друг F живет по соседству. Кроме того, предположим, что ваш второй друг G находится в вашем доме.

Теперь представьте, что вы даете G лист бумаги с вопросом на него и просите его отнести его к F.

Как только вопрос отправлен, представьте, что вы отправляете G, чтобы получить ответ F. Это похоже на вызов recv. G будет ждать, пока F не запишет свой ответ, а затем принесет его вам. G не сразу оборачивается и возвращается, если F еще не написал это.

Отсюда и разрыв. G действительно знает о "F написал!" события, но вы не. Вы не смотрите прямо на лист бумаги.

Установка таймаута означает, что вы говорите G подождать не более некоторого времени, прежде чем сдаться и вернуться. В этой ситуации G все еще ждет записи F, но если F не пишет в x миллисекунды, G оборачивается и возвращается с пустыми руками.

По сути, псевдокод recv выглядит примерно так:

1) is data available?
  1a) Yes: read it and return
  1b) No: GOTO 2
2) Wait until an event is received
  2a) GOTO 1

Я знаю, что это было ужасно запутанное объяснение, но моя главная мысль такова: recv взаимодействует с событиями, а не с вашим кодом. recv блокируется, пока одно из этих событий не будет получено. Если установлен тайм-аут, он блокируется до тех пор, пока не будет получено одно из этих событий или не истечет тайм-аут.

Сокеты НЕ управляются событиями по умолчанию. Вы должны написать дополнительный код, чтобы включить это. Вместо этого изначально создается сокет в режиме блокировки. Это означает, что вызов send(), recv(), или же accept() по умолчанию блокирует вызывающий поток до тех пор, пока запрошенная операция не будет завершена.

За recv()это означает, что вызывающий поток блокируется до тех пор, пока не будет доступен хотя бы 1 байт для чтения из буфера приема сокета или пока не произойдет ошибка сокета, в зависимости от того, что произойдет раньше. SO_RCVTIMEO позволяет установить таймаут на блокировку чтения так recv() выходит с WSAETIMEDOUT ошибка, если никакие входящие данные не становятся доступными до истечения времени ожидания.

Другой способ реализовать тайм-аут - установить сокет в неблокирующий режим вместо ioctlsocket(FIONBIO) а затем позвоните select() с таймаутом, затем позвоните recv() или же accept() только если select() сообщает, что сокет находится в читаемом состоянии, и send() только если select() сообщает, что сокет находится в состоянии записи. Но для этого требуется больше кода для управления случаями, когда сокет переходит в состояние блокировки, что приводит к сбою операций с WSAEWOULDBLOCK ошибки.

Другие вопросы по тегам