closesocket()因WSAEOPNOTSUPP而失败

时间:2009-05-18 18:07:03

标签: winapi sockets

我有一个使用套接字的应用程序(我没有写,所以请耐心等待)当我尝试关闭套接字时,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 个答案:

答案 0 :(得分:2)

你没有检查closesocket()上的返回码,这意味着WSAGetLastError()可能与closesocket操作有关,也可能没有。

答案 1 :(得分:0)

我不是Windows套件大师,但我还是会尝试一下.. 您确定WSAGetLastError()返回的代码涉及对closesocket()的调用吗?

引用msdn

  

...这是必要的,因为某些功能可能将上一个扩展错误代码重置为0,如果它们成功...

我假设你可能有一个先前的套接字相关调用失败(?)。 Msdn告诉每个套接字相关的调用后,你必须通过调用WSASetLastError()来阻止它。

  

要专门重置扩展错误代码,请使用WSASetLastError函数调用,并将iError参数设置为零。

答案 2 :(得分:0)

错误状态几乎肯定会从之前的操作中遗留下来。 Winsock函数在成功时通常不会清除错误状态。

检查closesocket()的返回码。如果这不表示错误,那么WSAGetLastError()的值是没有意义的。

答案 3 :(得分:0)

错误代码由recv遗留,因为Windows xp不支持标志MSG_WAITALL