|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Расскажите, как правильно и что я делаю не так. Читаем здесь 1. Call WSAEventSelect to register for FD_CLOSE notification. 2. Call shutdown with how=SD_SEND. 3. When FD_CLOSE received, call the recv or WSARecv until the function completes with success and indicates that zero bytes were received. If SOCKET_ERROR is returned, then the graceful disconnect is not possible. 4. Call closesocket.Т.е. после вызова shutdown, к нам приходит FD_CLOSE, на него нужно прочитать все что осталось, а потом закрыть сокет. Делаю так Инициализация Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28.
Но FD_CLOSE ко мне уже приходит с LError = WSAECONNABORTED и recv возвращает WSAECONNRESET. Значит ли это, что код должен быть таким Код: pascal 1. 2. 3. 4. 5. 6. 7. 8.
? И второй вопрос. Вот здесь алгоритм немного другой Client sideServer side(1) Invokes shutdown(s, SD_SEND) to signal end of session and that client has no more data to send.(2) Receives FD_CLOSE, indicating graceful shutdown in progress and that all data has been received.(3) Sends any remaining response data.(local timing significance only) Gets FD_READ and calls recv to get any response data sent by server .(4) Invokes shutdown(s, SD_SEND) to indicate server has no more data to send.(5) Receives FD_CLOSE indication.(local timing significance only) Invokes closesocket .(6) Invokes closesocket.Т.е. здесь написано, что после shutdown() мы должны штатно обработать FD_READ, а потом когда придет FD_CLOSE просто закрыть сокет. Если делаю так Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
Тогда на FD_READ LError = 0, а сам recv возвращает WSAECONNRESET и после этого приходит FD_CLOSE с LError = WSAECONNABORTED Так все таки, по какому алгоритму работать и как реагировать на ошибки? С уважением, Vasilisk ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 15:25 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_Так все таки, по какому алгоритму работать и как реагировать на ошибки? Я работаю по второму, поскольку первый подразумевает использование подписок и прочую виндомуть, а у меня чисто BSD сокеты. Никаких ошибок не возникает, ты закрываешь свой конец с помощью shutdown и когда другой конец согласится и точно так же закроет свой - можно закрыть сокет. То есть когда ты хочешь порвать соединение - делаешь shutdown(SD_SEND) и больше ничего. Когда получаешь 0 из recv() - делаешь shutdown(SD_SEND) (если не делал его раньше и это тот конец инициализировал разрыв) + closesocket(). Всё. Судя по ошибкам - ты упустил из виду необходимость делать shutdown и на другой стороне. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 15:37 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Судя по ошибкам - ты упустил из виду необходимость делать shutdown и на другой стороне. Dimitry Sibiryakov То есть когда ты хочешь порвать соединение - делаешь shutdown(SD_SEND) и больше ничего. Dimitry Sibiryakov Когда получаешь 0 из recv() - делаешь shutdown(SD_SEND) (если не делал его раньше и это тот конец инициализировал разрыв) + closesocket(). И еще, этот сервер отсылает пакет сразу после коннекта. Вот этого пакета я не вижу, даже если перед shutdown поставить Sleep Ну и еще вопрос - а зачем этот shutdown нужен? Или вызов closesocket может не дойти до удаленной стороны? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 16:35 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_А closesocket когда? После получения 0 из recv(). _Vasilisk_Но сказано, что после shutdown нужно еще прочитать данные. После другого shutdown. У сокета есть дырка в которую ты пихаешь данные и дырка из которой ты их читаешь. shutdown (по-хорошему) надо вызывать для каждой из дырок в отдельности. То есть: 1) shutdown для send-дырки - SD_SEND; 2) Читаешь из recv-дырки (вот тут должен прийти твой "пакет сразу после коннекта"); 3) shutdown для recv-дырки (ну или сразу для обоих дырок - SD_BOTH - чтобы не париться). Теперь сокет официально закрыт и его можно подчистить вызовом closesocket(). _Vasilisk_Или это не обязательно? В экстренных случаях, когда "бросай мешки, вокзал отходит", ты просто вызываешь shutdown(SD_BOTH) + closesocket(). При этом ты теряешь недочитанные данные с той стороны. Тот самый "пакет сразу после коннекта". _Vasilisk_Ну и еще вопрос - а зачем этот shutdown нужен? Или вызов closesocket может не дойти до удаленной стороны? closesocket - чисто локальный вызов чтобы освободить хэндл, буфера и т.п., он не уходит на удалённую сторону. Точнее уходит, но в виде RST-пакета если перед ним не был отправлен FIN-пакет. Что и вызывает получение WSAЕCONNRESET на другой стороне. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 16:51 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov После получения 0 из recv(). Dimitry Sibiryakov 2) Читаешь из recv-дырки (вот тут должен прийти твой "пакет сразу после коннекта"); Dimitry Sibiryakov Что и вызывает получение WSAЕCONNRESET на другой стороне. Еще раз. Все происходит на клиенте. 1. После успешного коннекта я сразу (или после Sleep(1000)) я вызываю shutdown 2. Ко мне приходит FD_READ, но при попытке сделать recv() я получаю WSAЕCONNRESET 3. Когда ко мне приходит FD_CLOSE, оно уже приходит с ошибкой WSAECONNABORTED ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 17:04 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Все. Разобрался. Чуть позже распишу ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 17:09 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Еще вопрос: Код: pascal 1.
что делает? ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 17:14 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_что делает? Закрывает дырку из которой читаешь. Дропает принятые, но непрочитанные данные. При нормальных условиях никогда не используется. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 17:47 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov closesocket - чисто локальный вызов чтобы освободить хэндл, буфера и т.п., он не уходит на удалённую сторону. Точнее уходит, но в виде RST-пакета если перед ним не был отправлен FIN-пакет. Что и вызывает получение WSAЕCONNRESET на другой стороне. ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 19:12 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_ Разобрался. Если убрать отладчик, то вот такая схема работает Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28.
Т.е. в чистом виде второй алгоритм. При этом первый recv читает данные, а второй возвращает WSAEWOULDBLOCK, что логично. А потом прилетает FD_CLOSE с ошибкой WSAECONNABORTED Если же работать по первому алгоритму Код: pascal 1. 2. 3. 4. 5. 6. 7. 8.
То recv сразу возвращает WSAЕCONNRESET ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 20:16 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_ Код: sql 1. 2. 3.
Вот тут перед closesocket должен вызываться shutdown(SD_BOTH) именно на случай, если сервер решил закрыть коннект по собственной инициативе. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 20:22 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov Вот тут перед closesocket должен вызываться shutdown(SD_BOTH) именно на случай, если сервер решил закрыть коннект по собственной инициативе. А теперь последний и очень дурацкий вопрос Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.
connect возвращает 0, а recv - WSAЕCONNRESET. Это как такое может быть? Причем это наблюдается для любого несуществующего хоста, но строго для 21 порта. Для остальных портов connect честно возвращает WSAETIMEDOUT. Что это за барабашка? На реальный сервер - коннект без проблем Update: похоже это наблюдается только в 192.168.1.ХХХ сети, к которой я подключаюсь через VPN ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 20:56 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_Что это за барабашка? WireShark в руки и смотреть с каким TTL приходит RST пакет от этого барабашки. По результатам - прицельный дихлофос. https://portal.nutanix.com/page/documents/kbs/details?targetId=kA00e000000LTA6CAO Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 21:13 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_ Код: sql 1. 2. 3. 4.
И ещё на всякий случай: спать именно здесь - очень плохая идея, поскольку события сокета в его собственной очереди стакаются и ивенты приходят упакованными, а ты их проверяешь на равенство вместо битовых операций, так что можешь потерять некоторые (а то и все). PS: CASE здесь использовать вообще нельзя. Надо проверять каждый отдельный бит, причём FD_READ лучше проверять перед FD_CLOSE, ибо они часто приходят парой. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
09.12.2021, 23:22 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov И ещё на всякий случай: спать именно здесь - очень плохая идея, Dimitry Sibiryakov PS: CASE здесь использовать вообще нельзя. Надо проверять каждый отдельный бит, И коды ошибок в WSAEnumNetworkEvents приходят массивом, а здесь один код в старшем слове ... |
|||
:
Нравится:
Не нравится:
|
|||
10.12.2021, 10:40 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Dimitry Sibiryakov WireShark в руки и смотреть с каким TTL приходит RST пакет от этого барабашки. ... |
|||
:
Нравится:
Не нравится:
|
|||
10.12.2021, 13:13 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
Чудит OpenVPN сервер. На сервере на VPN интерфейсе я эти пакеты вижу, а на внутреннем уже нет ... |
|||
:
Нравится:
Не нравится:
|
|||
10.12.2021, 13:40 |
|
Алгоритм вызова shutdown сокета
|
|||
---|---|---|---|
#18+
_Vasilisk_В обоих пакетах туда и обратно стоит 128. То есть вредитель прямо на первом хопе если вообще не локальный. Posted via ActualForum NNTP Server 1.5 ... |
|||
:
Нравится:
Не нравится:
|
|||
10.12.2021, 14:05 |
|
|
start [/forum/topic.php?fid=58&msg=40118742&tid=2036797]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
39ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
56ms |
get tp. blocked users: |
1ms |
others: | 283ms |
total: | 422ms |
0 / 0 |