2009-05-18 7 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은 각 소켓 관련 전화 후, 당신은, 특히 확장 된 오류 코드를 재설정하려면 0

WSASetLastError()를 호출하여 그 방지해야 제로로 설정 iError 매개 변수와 함께 WSASetLastError 함수 호출을 사용하는 것이 알려줍니다.

0

오류 상태는 거의 이전 작업에서 남겨 둡니다. Winsock 함수는 일반적으로 성공할 때 오류 상태를 지우지 않습니다.

closesocket()에서 리턴 코드를 확인하십시오. 이것이 오류를 나타내는 것이 아니라면 WSAGetLastError()의 값은 의미가 없습니다.

0

MSG_WAITALL 플래그가 Windows에서 지원되지 않으므로 recv에서 오류 코드가 남습니다. xp

관련 문제