По умолчанию, если другая сторона соединения исчезает, не прерывая соединение должным образом, ОС на вашей стороне не знает, что дальнейшие данные не появятся. Вот почему recv()
будет блокироваться навсегда в этой ситуации.
Если вы хотите получить тайм-аут, установите для него неблокирующий и используйте select()
, чтобы дождаться, когда он станет читаемым. select()
позволяет указать время ожидания.
В качестве альтернативы вы можете установить опцию сокета SO_KEEPALIVE
с помощью setsockopt()
. Это позволит отправлять TCP keepalives, что позволит вашей стороне обнаруживать устаревшее соединение. (Обратите внимание, что с настройками по умолчанию для определения того, что соединение ушло, может потребоваться время ).
Спасибо за ответ. Как насчет отправки? Будет ли она также сталкиваться с аналогичной проблемой? – Jay
@Jay: 'send()' будет разблокировать после (в худшем случае) 4,5 минуты с ошибкой, так как другая сторона не будет отправлять ACK, а ACK имеют таймаут. TCP - это протокол, ориентированный на данные: до тех пор, пока вы не видите ошибки, данные не были потеряны. Но он ничего не может сказать о состоянии другой стороны. В вашем случае это ничем не отличается от простоя TCP-соединения. Вот почему ваш 'recv()' блокирует по существу навсегда. – Dummy00001
Хорошо. Еще раз спасибо. Если я использую Non-Blocking Sockets, то он всегда будет давать мне EWOULDBLOCK для отправки и возврата в этом сценарии правильно? – Jay