检测到FD_ACCEPT,然后调用“接受”#39;以10038失败 - WSAENOTSOCK

时间:2015-10-08 21:27:02

标签: c++ sockets winsock2

基本上,就是这样。同时,客户对连接的呼吁是成功的。怎么可能?我还没有添加任何代码,因为我不知道错误在哪里。

服务器:检测FD_ACCEPT。呼叫接受()失败。

客户端:调用connect()成功。然后它检测FD_CONNECT。以下send()成功。之后的send()失败(10053 - WSAECONNABORTED)。

void Server::get_addressinfo() {
    // Resolve the local address and port to be used by the server
    const char * p = port.c_str();
    int iResult = getaddrinfo(NULL, p, &hints, &result);
    if (iResult != 0) {
        throw MyException("getaddrinfo failed.");
    }
}

void Server::create_socket() {
    ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
    if (ListenSocket == INVALID_SOCKET) {
        throw MyException("socket creation failed.");
    }
}

void Server::bind_socket() {
    int iResult = bind(ListenSocket, result->ai_addr, (int) result->ai_addrlen);
    if (iResult == SOCKET_ERROR) {
        closesocket(ListenSocket);
        throw MyException("bind failed.");
    }
}

void Server::listen_for_connection() {
    int iResult = listen(ListenSocket, SOMAXCONN);
    if (iResult == SOCKET_ERROR) {
        closesocket(ListenSocket);
        throw MyException("listen failed.");
    }
}

void Server::goLive() {
    get_addressinfo();
    create_socket();
    bind_socket();
    listen_for_connection();
    wait_for(FD_ACCEPT);
    accept_connection();
}

void Server::wait_for(u_int event_type) {
    WSAEVENT event = WSACreateEvent();
    WSAEventSelect(ListenSocket, event, event_type);
    WSAEVENT lphEvents[1] = {event};
    WSANETWORKEVENTS NetworkEvents = {0};
    int nReturnCode = WSAWaitForMultipleEvents(1, &lphEvents[0], false, WSA_INFINITE, false);
    if (nReturnCode==WSA_WAIT_FAILED) 
        throw MyException("WSA__WAIT_FAILED.\n");
    if (WSAEnumNetworkEvents(ListenSocket, lphEvents[0], &NetworkEvents) == SOCKET_ERROR) 
        throw MyException("WSAEnumNetworkEvents => SOCKET_ERROR.\n");
    WSACloseEvent(event);  ***// THIS WAS THE BUG !!!***
}

void Server::accept_connection() {
    ClientSocket = accept(ListenSocket, NULL, NULL);
    if (ClientSocket == INVALID_SOCKET) {
        closesocket(ListenSocket);
        throw MyException("accept failed.");
    }
}

1 个答案:

答案 0 :(得分:0)

我对代码进行了一些处理并使其更好,但是bug仍然在那里。现在我发现了有问题的一行:

WSACloseEvent(event);

在评论之后,服务器接受了连接。

从MSDN WSACloseEvent函数文档:

  

WSACloseEvent函数关闭事件对象的句柄并释放与事件对象关联的资源

我想这意味着它释放了socket =>因此10038 - WSAENOTSOCK。我堕落的套接字值不等于INVALID_SOCKET。因此我认为套接字是有效的。它不是......