closesocket () завершается неудачно с WSAEOPNOTSUPP - PullRequest
1 голос
/ 18 мая 2009

У меня есть приложение, использующее сокеты (которые я не написал, так что терпите меня), и когда я пытаюсь закрыть сокет, closesocket () завершается неудачно с ошибкой WSAEOPNOTSUPP, и сокет торчит ... как в, он не полностью удален.

Сокет создается следующим образом:

bool Socket::CreateConnection()
{
   int error;
   struct addrinfo hints;
   struct addrinfo *list = NULL;

   memset(&hints, 0, sizeof(hints));
   hints.ai_family = AF_INET;
   hints.ai_socktype = SOCK_STREAM;
   hints.ai_protocol = IPPROTO_TCP;

   error = getaddrinfo(socketAddress.c_str(), socketPort.c_str(), &hints, &list);
   if (error)
   {
      Log().RecordError("Unable to initialize connection to server", WSAGetLastError(), EventTypeError);
   }

   for (struct addrinfo *ptr = list; ptr != NULL; ptr = ptr->ai_next)
   {
      connection = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
      if (connection == INVALID_SOCKET)
      {
         Log().RecordError("Unable to initialize socket connection", WSAGetLastError(), EventTypeError);
         break;
      }

      error = connect(connection, ptr->ai_addr, (int)ptr->ai_addrlen);
      if (error == SOCKET_ERROR)
      {
         closesocket(connection);
         connection = INVALID_SOCKET;
         continue;
      }
      break;
   }

   freeaddrinfo(list);

   return connection != INVALID_SOCKET;
}

И деструктор для класса:

Socket::~Socket()
{
   int error;

   if (connection != INVALID_SOCKET)
   {
      continueReading = false;

      error = shutdown(connection, SD_SEND);
      if (error != SOCKET_ERROR)
      {
         /* Finish any necessary receives to politely close the socket */
         int length;
         do
         {
            char buffer[1024];
            length = recv(connection, buffer, sizeof(buffer)/sizeof(*buffer), MSG_WAITALL);
         } while (length > 0);
      }
      else
      {
         Log().RecordError("Error shutting down connection to server", WSAGetLastError(), EventTypeError);
      }

      closesocket(connection);  //Fails HERE
      int wsa_err = WSAGetLastError();
      if(wsa_err)
          Log().RecordError("closesocket() error", wsa_err, EventTypeError);
   }

   if (winsockInitialized)
   {
      WSACleanup();
   }
}

Кто-нибудь знает, почему это произойдет ??

Ответы [ 4 ]

2 голосов
/ 18 мая 2009

Вы не проверяете код возврата в closesocket (), это означает, что WSAGetLastError () может или не может быть связан с операцией closesocket.

0 голосов
/ 27 октября 2009

Код ошибки оставлен в recv, так как флаг MSG_WAITALL не поддерживается в Windows XP

.
0 голосов
/ 24 мая 2009

Состояние ошибки почти наверняка осталось от предыдущей операции. Функции Winsock обычно не очищают состояние ошибки при успешном завершении.

Проверьте код возврата из closesocket (). Если это не указывает на ошибку, то значение WSAGetLastError () не имеет смысла.

0 голосов
/ 18 мая 2009

Я не гуру Windows-сокетов, но попробую еще ... Вы уверены, что код, возвращаемый WSAGetLastError(), относится к вызову closesocket()?

Цитирование msdn :

... Это необходимо, потому что некоторые функции могут сбрасывать последний расширенный код ошибки на 0, если они завершаются успешно ...

Я предполагаю, что у вас может быть предыдущий вызов, связанный с сокетом, который не удался (?). Msdn сообщает, что после каждого вызова, связанного с сокетом, вы должны предотвратить это, вызвав WSASetLastError() с 0.

Чтобы специально сбросить расширенный код ошибки, используйте вызов функции WSASetLastError с параметром iError, установленным в ноль.

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