Подтвердить что ты не робот

Функция сокета recv() возвращает данные длиной 0

У меня есть приложение, которое установило соединение сокета на номере порта 5005 с другим устройством (аппаратное устройство с веб-сервером).

Теперь, если мое аппаратное устройство отключится, я потерял соединение с устройством.

  • Означает ли это, что сокет я был использование до сих пор становится недействительным.

  • Получаю ли я специальное сообщение, например нулевой символ или что-то еще это отключение происходит.

  • Если соединение сокета я было став недействительным, то почему does not функция recv() throw и SOCKET_ERROR. Вместо почему я получаю данные 0 длина.

Спасибо

4b9b3361

Ответ 1

Когда recv возвращает значение 0, это означает, что соединение было закрыто.

См. recv справочная страница:

Эти вызовы возвращают количество полученных байтов или -1, если ошибка произошло. Возвращаемое значение будет равно 0, когда сверстник выполнил упорядоченное завершение работы.

В ответ на вопроС# 1 да, сокет теперь недействителен. Вы должны создать новый сокет и соединение для дальнейших сообщений.

Edit

Теперь, когда valdo указал ниже, есть также возможность иметь полузакрытое TCP-соединение, в котором вы не можете получить больше, но вы можете продолжать писать в сокет, пока не закончите отправлять свои данные. См. Эту статью для получения дополнительной информации: TCP Half-Close. Звучит не так, как будто у вас есть эта ситуация.

В ответе на вопрос № 2 существуют два способа обнаружения закрытого сокета. Это предполагает, что сокет прошел через упорядоченное выключение, что означает, что одноранговый узел называется shutdown или close.

Первый способ - прочитать из сокета, в этом случае вы получите возвращаемое значение 0. Другим способом является запись в сокет, что вызовет сигнал SIG_PIPE, указывающий на сломанный канал.

Чтобы избежать сигнала, вы можете установить опцию MSG_NOSIGNAL socket, и в этом случае send вернет -1 и установит errno до EPIPE.

Ответ 2

Согласитесь с Робертом С. Барнсом. Кроме утверждения, что сокет теперь "недействителен".

Это все еще актуально. Вы можете использовать его. Вы даже можете отправить данные сверстнику. Единственное, с чем вы не можете сделать, это вызов recv.

Ответ 3

Предположим, вы используете TCP для связи с вашим устройством.

  • Сам сокет по-прежнему "действителен", однако соединение было потеряно.

  • Вы получаете возвращаемое значение 0 для recv(), когда соединение было закрыто другим хостом (если это отключение было изящным или не имеет значения)

  • Функции сокетов похожи на функции C: они не выбрасываются, потому что их можно использовать в программах C, где существуют исключения не.

Ответ 4

Если recv возвращает 0, это означает, что сверстник закрыл сокет.

recv не будет бросать, потому что его функция C.

Если ошибка recv вернет -1. В этом случае ваше приложение должно проверить тип ошибки. Обратите внимание, что возврат -1 не означает, что сверстник закрыл его.

Ответ 5

Учитывая, что вы разговариваете с веб-сервером, я предполагаю, что вы используете сокеты TCP.

Чтобы ответить:

  • Сокеты не становятся недействительными из-за отключения; они просто переходят в отключенное состояние. По-прежнему безопасно вызывать операции сокетов на них.

  • Вы не получите никаких специальных сообщений при отключении. Если вы вызываете recv() блокирующим образом, он будет возвращаться при отключении, а количество байтов, возвращенных от вызова, не будет соответствовать количеству запрошенных вами байтов.

  • На самом деле нет ответа на этот вопрос: как API-интерфейс сокета был реализован изначально, и мы придерживаемся этой реализации, поскольку все реализуют Berkley Sockets.