-- client sends request
send()
send()
shutdown(SHUT_WR) -- starts waiting for a reply
read()
...
-- server accepts conn and reads request
read()
...
send(). -- writes reply
closesocket() --and immediately closes its socket
При этом клиент после closesocket() на сервере периодически получает RST. В моём понимании, это означает, что на сервере в recv queue ещё лежат непрочитанные данные. Но:
1. если перед socketclose() на сервере сделать recv(), то он прочитает 0 байт.
2. проблема проходит, если перед closesocket() на сервере вызвать shutdown(SHUT_BOTH).
Здравствуйте, tdiff, Вы писали:
T>При этом клиент после closesocket() периодически получает RST. В моём понимании, это означает, что на сервере в recv queue ещё лежат непрочитанные данные. Но:
Откуда ты знаешь, что получает клиент после closesocket()?
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, tdiff, Вы писали:
T>>При этом клиент после closesocket() периодически получает RST. В моём понимании, это означает, что на сервере в recv queue ещё лежат непрочитанные данные. Но:
Pzz>Откуда ты знаешь, что получает клиент после closesocket()?
К сожалению, у меня нет возможности запустить Wireshark, но клиент (написан на c#) выходит из Receive с error = SocketError.ConnectionReset.
Здравствуйте, tdiff, Вы писали:
T>К сожалению, у меня нет возможности запустить Wireshark, но клиент (написан на c#) выходит из Receive с error = SocketError.ConnectionReset.
Здравствуйте, Pzz, Вы писали:
Pzz>Здравствуйте, tdiff, Вы писали:
T>>К сожалению, у меня нет возможности запустить Wireshark, но клиент (написан на c#) выходит из Receive с error = SocketError.ConnectionReset.
Pzz>Ты SO_LINGER трогал?
А, я понял, что плохо написал (обновил описание). В моей ситуации сокет первым закрывает сервер (вызывает closesocket). В этот момент клиент висит на recv(). Соответственно, rst получает клиент как ошибку из recv.
Намеки 1 и 2 относятся к серверу.
Статью уже видел, но из нее непонятно, почему это работает.
на сервере есть очередь, иногда
если сделать клозе сокет то оно видя не обработанную очередь отправляет ресет кленту
но если даже имея не обработанную входящую очередь, сделать шут вр
то думаю(надо смотреть тцп дампом)
либо
1) канал финализируется и закрывается у клиента, и ресет который может отправить сервер уже клиент игнорит
либо
2) сервер видя что запись потушили, уже не отправляет ресет из за того что есть не обработанная очередь в сокете
Здравствуйте, tdiff, Вы писали:
Pzz>>Ты SO_LINGER трогал?
T>Нет
Очень все это выглядит странно. Если на сервере recv() вернул ноль, значит, все уже вычитано, и больше не ожидается (сервер осознал, что клиент сделал shutdown() на запись).
А сокет ты сам полностью контролируешь, или есть еще какой-то код, который с ним чего-то может сделать?
Re[6]: RST на клиенте после socketclose на сервере
R>на сервере есть очередь, иногда R>если сделать клозе сокет то оно видя не обработанную очередь отправляет ресет кленту R>но если даже имея не обработанную входящую очередь, сделать шут вр R>то думаю(надо смотреть тцп дампом) R>либо R>1) канал финализируется и закрывается у клиента, и ресет который может отправить сервер уже клиент игнорит R>либо R>2) сервер видя что запись потушили, уже не отправляет ресет из за того что есть не обработанная очередь в сокете
ок, спасибо. Я примерно так предполагал, но нигде не видел доки, подтверждающей это.
У меня осталось непонимание, почему read перед close на сервере возвращает ноль? Т.е. очереди нет. Разве что я мог еще не прочитать EOF, например...
Re[7]: RST на клиенте после socketclose на сервере
Здравствуйте, tdiff, Вы писали:
T>У меня осталось непонимание, почему read перед close на сервере возвращает ноль? Т.е. очереди нет. Разве что я мог еще не прочитать EOF, например...
Здравствуйте, Pzz, Вы писали:
Pzz>Очень все это выглядит странно. Если на сервере recv() вернул ноль, значит, все уже вычитано, и больше не ожидается (сервер осознал, что клиент сделал shutdown() на запись).
Pzz>А сокет ты сам полностью контролируешь, или есть еще какой-то код, который с ним чего-то может сделать?
Полностью сам, если не считать какой-нибудь DLP, но это уже совсем эзотерика
Re[8]: RST на клиенте после socketclose на сервере
R>блочный или нон блок сервер ? R>надо смотреть тцп дампом что там,еоф или что то другое
R>код ошибки при получения нуля надо смотреть, хотя я хз как там в шарпе, R> если бы была ошибка всегда был ексепшин ? или надо иногда вручную проверять ?
У меня клиент на шарпе, сервер на плюсах. Он совсем простенький — создаёт по треду на каждое соединение, все сокеты блокирующиеся. Т.к. вся эта красота работает под виндой, recv = 0 означает конец стрима без ошибки.
TCP dump практически недоступен
Re[9]: RST на клиенте после socketclose на сервере