Завершение работы TCP с сокетами, подключенными через AcceptEx () - PullRequest
7 голосов
/ 07 февраля 2012

Документация для AcceptEx() гласит:

Когда эта операция успешно завершена, sAcceptSocket может быть передан, но только для следующих функций:

  • ReadFile
  • WriteFile
  • отправка
  • WSASend
  • recv
  • WSARecv
  • TransmitFile
  • closesocket
  • setsockopt (только для SO_UPDATE_ACCEPT_CONTEXT)

Обратите внимание, что shutdown() отсутствует в списке.Действительно, вызов shutdown(sAcceptSocket, SD_SEND) возвращает SOCKET_ERROR, а WSAGetLastError() приводит к ошибке WSAENOTCONN:

Запрос на отправку или получение данных был отклонен, поскольку сокет не подключен и (при отправке насокет датаграммы с использованием sendto call) адрес не был указан.

Почему нельзя отключить сокет, подключенный через AcceptEx()?Кроме того, почему сокет не отображается как подключенный, поскольку он уже получает данные (перекрывающаяся операция завершена и уведомление о завершении указывает, что было получено несколько size>0 байтов)?

1 Ответ

8 голосов
/ 07 февраля 2012

Вы должны позвонить setsockopt(SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT) после завершения AcceptEx().Принятый сокет не полностью связан со свойствами прослушивающего сокета и поэтому не будет находиться в полностью подключенном состоянии, пока не будет установлено значение SO_UPDATE_ACCEPT_CONTEXT.Это влияет на некоторые функции Winsock API, включая getpeername(), getsockname() и shutdown().

. Если вы используете ConnectEx() для установления исходящего соединения, вы должны вызвать setsockopt(SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT) после ConnectEx() завершается, прежде чем вы можете использовать shutdown().Это задокументированное поведение в MSDN.Это не говорит то же самое для AcceptEx() и SO_UPDATE_ACCEPT_CONTEXT, но shutdown() имеет аналогичное ограничение для сокетов, принятых AcceptEx().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...