recv () снабжают данные возврата функции сокетом с длиной как 0

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

Теперь, если мое устройство разъединяется затем, я освобождаю соединение с устройством.

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

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

  3. Если сокетное соединение, которое я имел, стало недопустимым затем, почему не делает recv () бросок функции сокета и SOCKET_ERROR. Вместо этого, почему я получаю данные 0 длин.

Спасибо

18
задан user207421 27 June 2018 в 02:28
поделиться

5 ответов

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

См. страницу руководства recv:

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

Отвечая на вопрос #1, да, сокет теперь недействителен. Вы должны создать новый сокет и соединение для дальнейшего взаимодействия.

Редактировать

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

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

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

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

35
ответ дан 30 November 2019 в 06:22
поделиться

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

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

10
ответ дан 30 November 2019 в 06:22
поделиться

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

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

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

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

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

1
ответ дан 30 November 2019 в 06:22
поделиться

Я полагаю, вы используете TCP для связи со своим устройством.

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

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

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

2
ответ дан 30 November 2019 в 06:22
поделиться

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

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

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

2
ответ дан 30 November 2019 в 06:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: