2009-05-18 51 views
1

我有一個應用程序使用套接字(我沒有寫,所以忍受着我),當我嘗試關閉套接字時,closesocket()失敗,錯誤WSAEOPNOTSUPP和套接字...在,它並沒有完全刪除。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(); 
    } 
} 

任何人都有一個線索,爲什麼會發生這種情況?

回答

2

您不檢查closesocket()上的返回碼,這意味着WSAGetLastError()可能與closesocket操作相關或可能不相關。

0

我不是Windows套接字大師,但我會試一試。 您確定WSAGetLastError()返回的代碼涉及closesocket()的調用嗎?

報價msdn

...這是必要的,因爲有些功能可能最後擴展錯誤代碼,如果他們成功重置爲0 ...

我想你可能有與之前套接字相關的調用失敗(?)。 MSDN告訴每個插座相關的呼叫後,必須防止通過調用WSASetLastError()以0

要明確重置擴展的錯誤代碼,使用WSASetLastError函數調用設置爲零IERROR參數。

0

錯誤狀態幾乎肯定是從先前的操作中遺留下來的。 Winsock函數通常不會在成功時清除錯誤狀態。

檢查來自closesocket()的返回碼。如果這並不表示錯誤,那麼WSAGetLastError()的值是沒有意義的。

0

錯誤代碼從recv遺留下來,因爲Windows xp不支持標誌MSG_WAITALL