FD_ACCEPT 检测到,但随后调用 'accept' 失败并显示 10038 - WSAENOTSOCK
FD_ACCEPT detected, but then call 'accept' fails with 10038 - WSAENOTSOCK
基本上就是这样。同时,客户端调用连接成功。这怎么可能?我没有添加任何代码,因为我不知道错误在哪里。
服务器:检测到 FD_ACCEPT。调用 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.");
}
}
我对代码进行了一些修改并使其变得更好,但错误仍然存在。现在我找到了有问题的行:
WSACloseEvent(event);
注释掉后,服务器接受了连接。
来自 MSDN WSACloseEvent 函数文档:
The WSACloseEvent function closes the handle to an event object and frees resources associated with the event object.
我猜这意味着它释放了套接字 => 因此 10038 - WSAENOTSOCK。我爱上了不等于 INVALID_SOCKET 的套接字值。因此我认为套接字是有效的。这不是...
基本上就是这样。同时,客户端调用连接成功。这怎么可能?我没有添加任何代码,因为我不知道错误在哪里。
服务器:检测到 FD_ACCEPT。调用 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.");
}
}
我对代码进行了一些修改并使其变得更好,但错误仍然存在。现在我找到了有问题的行:
WSACloseEvent(event);
注释掉后,服务器接受了连接。
来自 MSDN WSACloseEvent 函数文档:
The WSACloseEvent function closes the handle to an event object and frees resources associated with the event object.
我猜这意味着它释放了套接字 => 因此 10038 - WSAENOTSOCK。我爱上了不等于 INVALID_SOCKET 的套接字值。因此我认为套接字是有效的。这不是...