tcp closesocket метод сброса генерации winsock (RST)

Функция закрытия сокета Windows (closesocket) генерирует RST.

В Linux, когда я вызываю функцию close, чтобы закрыть TCP-сокет, он проходит через fin / ack с обоих клиентских серверов, и сокет закрывается.

Но в Windows Winsock всякий раз, когда я вызываю closesocket, он всегда генерирует сообщение RST.

Я пробовал использовать вызов выключения. Он генерирует FIN. Но в конце концов мне нужно вызвать closesocket, и он отправит RST.

Есть ли способ вызвать closesocket для освобождения ресурсов сокета без отправки сообщения RST.


person deshapriya debesh    schedule 07.03.2018    source источник
comment
Что ты делаешь до этого? Вы прочитали все входящие данные? Вы испортили SO_LINGER на розетке?   -  person user207421    schedule 08.03.2018
comment
ConnectSocket = socket (ptr- ›ai_family, ptr-› ai_socktype, ptr- ›ai_protocol); iResult = connect (ConnectSocket, ptr- ›ai_addr, (int) ptr-› ai_addrlen); iResult = выключение (ConnectSocket, SD_SEND); closesocket (ConnectSocket); WSACleanup (); Я закончил получать все данные. Но мне кажется, что сокет Windows никогда не проходит через четыре пути FIN / ACK, чтобы закрыть сокет. Он всегда отправляет RST всякий раз, когда вызывается colsesocket или завершение работы с SD_BOTH. Я ищу способ четырехстороннего FIN / ACK на закрытии сокета Windows, как это происходит в Linux.   -  person deshapriya debesh    schedule 08.03.2018
comment
Вы не должны размещать код в комментариях. Добавьте это к своему вопросу. Но данные свидетельствуют о том, что вы не прочитали все входящие данные. Вы действительно recv(), пока не получили нулевую прибыль?   -  person user207421    schedule 08.03.2018
comment
Извините за путаницу. Ты прав. Я не жду, пока recv () вернет ноль. В моем случае сервер является источником, а клиент - получателем. У меня есть условие, при котором я хочу закрыть клиентский сокет. Клиентский сокет SO_LINGER установлен на (ld.l_onoff = 1, ld.l_linger = 10). в этом случае я вызываю отключение клиентского сокета с помощью SD_SEND, а затем вызываю closesocket. Я ожидаю, что клиент дождется 10 секунд, чтобы прочитать все данные, и, если данные не остались, корректно закройте без отправки RST. Если через 10 секунд появятся какие-либо данные, отправьте RST.   -  person deshapriya debesh    schedule 08.03.2018
comment
А? Этот параметр SO_LINGER означает, что клиент будет ждать до 10 секунд, чтобы отправить все ожидающие данные, когда он закроет сокет. Единственный способ ожидания до 10 секунд для получения данных - это вызов SO_RCVTIMEO, или select(), и recv().   -  person user207421    schedule 08.03.2018


Ответы (2)


Есть несколько причин, из-за которых closesocket() может отправить RST вместо FIN:

  1. Вызывается, когда в приемном буфере сокета есть непрочитанные данные.
  2. Вызов его после того, как вы установили для параметра SO_LINGER значение «on» с нулевым таймаутом.
person user207421    schedule 08.03.2018

Если больше нет данных для отправки и / или получения, вы можете использовать shutdown ().

Пример: выключение (clisocket, SD_BOTH);

person user11082348    schedule 19.02.2019
comment
Никак не отвечает на вопрос. - person user207421; 05.06.2019