Чтобы было ясно, recv()
не должен потерпеть неудачу, если соединение было правильно закрыто. Он должен возвращать EOF (0 байт). recv()
не работает, соединение было закрыто аномально.
Чтобы проверить, было ли соединение закрыто без фактического получения данных, если это не было, лучше всего, возможно, вы можете позвонить по телефону recvmsg()
с флагом MSG_PEEK
. Попросите только один байт. Если соединение было закрыто, вы получите EOF (нормальное закрытие) или ошибку (аномальное закрытие). Если он не был закрыт, вы получите либо EAGAIN
(при условии, что вы вставили сокет в неблокирующий режим), либо один байт данных. Итак, да, технически вы получили байт данных, но из-за MSG_PEEK
ядро не фиксирует тот факт, что вы это сделали, так что, как будто вы этого не сделали. Все это предполагает, что вы уже прочитали из буфера ядра все данные из потока, который был до предполагаемой ошибки.
Конечно, комментарий к комментарию rakib применяется: «Невозможно проверить, жив ли удаленный хост, если вы не хотите давать или возвращать данные». Это означает, что этот метод не будет обнаруживать сценарии, такие как удаленный хост, исчезающий из сети, не закрывая соединение, и т. Д.
Невозможно проверить, жив ли удаленный хост, если вы не хотите давать или возвращать данные. –
Я думаю, что вы хотите использовать TCP Keep-Alive (используя 'SO_KEEPALIVE') – Hasturkun
@Hasturkun Это все еще требует от вас ввода/вывода, иначе вы никогда не узнаете. – EJP