Смерть сокета меняет свое поведение несколькими способами, поэтому оба метода действительны:)
С помощью обоих методов вы фактически проверяете те части поведения сокета, которые меняются после отключения.
Я не совсем понимаю его заявление о вызове Receive (), чтобы убедиться, что удаленная конечная точка действительно получила все отправленные мной данные. (Блокирует ли получение сокеты, пока буфер отправки не опустеет?)
TCP
- это надежный протокол, который означает, что каждый отправленный вами пакет должен быть подтвержден. Подтверждение подразумевает отправку пакетов с установленным битом ACK
. Эти пакеты могут содержать или не содержать дополнительные (полезные данные) данные.
Когда сокет подключен, Receive()
будет блокироваться, пока сокет не получит пакет с непустой полезной нагрузкой. Но когда сокет отключен, Receive()
вернется, как только прибудет последний пакет ACK
.
Вызов Receive()
гарантирует, что вы либо получите этот последний ACK
пакет от удаленной конечной точки, либо произойдет тайм-аут отключения, и вы сможете получить больше ничего об этом розетка.
Пример на той же странице показывает, как это сделать. (Интересно, почему он выделяет 1-байтовый массив, хотя и вызывает Send с длиной 0?) Но в сообщении Иана Гриффитса говорится, что я должен читать из сокета, а не отправлять через него.
При send()
в сокете вы фактически пытаетесь добавить некоторые данные в конец очереди сокета. Если в буфере осталось место, то ваш Send()
мгновенно возвращается, если нет, блоки Send()
, пока не будет места.
Когда сокет находится в отключенном состоянии, стек TCP/IP
предотвращает все дальнейшие операции с буфером, поэтому Send()
возвращает ошибку.
Send()
реализует базовую проверку указателя, это означает, что она не работает, когда ей передается указатель NULL
. Возможно, вы можете передать любую ненулевую константу в качестве указателя, но вам лучше выделить 1 байт, а не делать константу up - на всякий случай.
Вы можете использовать любой метод, который вам нравится, поскольку ни один из них не потребляет ресурсов. Пока они используются для проверки сокетного соединения, они идентичны.
Что касается меня, я бы предпочел Receive()
, так как это то, что вы обычно запускаете в цикле и ждете. Вы получаете ненулевое значение от Receive()
, вы обрабатываете данные; Вы получаете ноль, вы обрабатываете отключение.