Здравствуйте, Michael Chelnokov, Вы писали:
MC>Здравствуйте, Diablo_II, Вы писали:
D_I>>Проверок не много. Есть необходимость чётко знать, что происходит:
MC>Настоятельно рекомендую не привязываться к конкретным кодам ошибок. Обычно стараются свести лишь к определению успеха/неудачи. Иначе придется обрабатывать слишком много случаев и все это может перестать работать в следующей версии системы.
Тут согласен — вопрос не в кодах ошибок, а в том как распознать ситуацию.
Ждущий AcceptEx завершается с некими параметрами на IOCP.
Как чётко отделить локальное закрытие сокета (я сам его закрыл в другом потоке) от удалённого закрытия сокета (клиент вызвал closesocket).
По поводу этого кстати заметил в ходе экспериментов следующие 2 ситуации.
— В сервере висит запрос AcceptEx запрос с ожиданием данных.
— Если мой клиент подключается и потом не посылая данных делает closesocket.
— AcceptEx сваливается на IOCP c кодом ERROR_SUCCESS и dwNumberBytes == 0.
причём самое смешное — на этот сокет — по факту уже не имеющий подключения можно сделать WSARecv — который отработает без ошибок.
Правда для него всегда будет dwNumberBytes == 0 возвращаться.
но что странно — взял netcat.exe (всем не безизвестный)
— В сервере висит запрос AcceptEx запрос с ожиданием данных.
— netcat'ом устанавливаем соединенеие и рвём его не отправляя данных.
— AcceptEx сваливается на IOCP c кодом ERROR_NETNAME_DELETED.
Откуда такая разница в поведении? Вроде оба делают судя по коду closesocket?
D_I>> — Локальный дисконект (сервер отключает клиента следуя своей логике) D_I>> — Удалённый дисконект (клиента отключается от сервера)
MC>Активные операции WSASend/WSARecv обламываются (например, с WSAECONNABORTED в первом случае, и с WSAECONNRESET во втором). Если таких операций в данный момент нет, то ничего не происходит. При дальнейшем использовании хэндла сокета будет WSAENOTSOCK, кажется.
На сколько я понял ошибки типа WSAECONNABORTED, WSAENOTSOCK, WSAECONNRESET и пр. WSAxxx возвращаются только при немосредственном вызове WSARecv и пр функций.
Т.е. они никогда (я такого не разу не видел) на возвращаются как ошибки при завершении операции через IOCP.
При завершении опрации через IOCP вываливаются другие коды типа ERROR_NETNAME_DELETED, ERROR_OPERATION_ABORTED и пр.
D_I>> — Сервер останавливается
MC>Т.е. закрывается слушающий сокет? Висящие AcceptEx отвалятся с ошибкой (не помню какой, легко устанавливается экспериментом).
D_I>> — Ошибки сокетов
MC>Соответствующий код ошибки активных операций будет возвращен через порт. Например, WSAENETDOWN.
как уже сказал выше WSAxxx — никогда на прт не валяться? или я не прав? если не прав то как воспроизвести?
У меня до этого ни разу не получилось.
D_I>> — Клиент подключился и сразу отключился (события то сработаю, а как их задетектить, по каким сочетаниям параметров в Completion?) — реального то соединения уже нет.
MC>AcceptEx успешно пройдет, но последующий вызов WSASend/WSARecv вернет ошибку (например, WSAENOTCONN или WSAECONNRESET, не помню точно). Если при AcceptEx идет попытка принять данные, то ошибку вернет уже он.
Всё тот же WSAххх который невозможно увидеть при завершении через IOCP.
D_I>> — Клиент подключился и был отклонён по таймауту — реального то соединения тоже уже нет.
MC>Кем отклонен? Если системой, то тоже, что и в первых двух случаях, но с ошибкой WSAETIMEDOUT. Если вашим приложением, то это первый вариант, WSAECONNABORTED.
Всё тот же WSAххх который невозможно увидеть при завершении через IOCP.
Вот так... фигня какая-то.
Или руки совсем кривеникие стали у меня.