AcceptEx 返回 1022 (WSAEINVAL)...我做错了什么?
我正在尝试为完成端口编写一个小型测试服务器。 但是当我尝试调用 AcceptEx 时...它总是返回 WSAEINVAL 作为 Winsock 错误代码... 我真的不明白我的错误是什么
http://codepad.org/NEXG3Ssh <- 键盘上的代码
和
StartWinsock();
cout << "Winsock initiated\n";
//Get the number of processors
DWORD ulProcessors = GetNumberOfProcessors();
cout << "Number of Processors/Threads, that will be used: " << ulProcessors << endl;
//Create an completion port
hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, ulProcessors);
if(hCompletionPort == NULL)
ErrorAbort("Could not create completion port");
cout << "Completion Port created\n";
//Create threads
CreateThreads(ulProcessors);
cout << "Threads created\n";
//Create socket
AcceptorSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addrinfo *final, hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE;
if(getaddrinfo(NULL,"12345", &hints, &final))
ErrorAbort("Could not retrieve address information");
if(bind(AcceptorSock,final->ai_addr, final->ai_addrlen))
ErrorAbort("Could not bind socket");
freeaddrinfo(final);
cout << "Acceptor socket created and bound\nStarting to listen on the acceptor socket\n";
if(listen(AcceptorSock, 2))
ErrorAbort("Can´t listen on the socket");
//Add acceptor socket file handle to be observed by the completion port
if(CreateIoCompletionPort((HANDLE)AcceptorSock, hCompletionPort, NEW_CONNECTION, 0) != hCompletionPort)
ErrorAbort("A new completion port has been created instead of using the existing one");
cout << "Acceptor socket associated with the completion port\n";
ResumeThreads(2);
char lpOutputBuf[1024];
int outBufLen = 1024;
DWORD dwBytes;
OVERLAPPED over;
SOCKET newSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
while(true)
{
memset(&over, 0, sizeof(over));
if(AcceptEx(AcceptorSock, newSock, lpOutputBuf, outBufLen - ((sizeof(sockaddr_in) + 16) * 2), sizeof(sockaddr_in)+16, sizeof(sockaddr_in)+16, &dwBytes, &over) == FALSE)
{
int x = WSAGetLastError();
if( x != WSA_IO_PENDING)
ErrorAbort("Could not acceptex a new connection");
}
}
I am trying to code a small test-server for completion ports.
But when I try to call AcceptEx... it always returns WSAEINVAL as the winsock error code...
I don´t really get what was my mistake
http://codepad.org/NEXG3Ssh <- code on codepad
and
StartWinsock();
cout << "Winsock initiated\n";
//Get the number of processors
DWORD ulProcessors = GetNumberOfProcessors();
cout << "Number of Processors/Threads, that will be used: " << ulProcessors << endl;
//Create an completion port
hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, ulProcessors);
if(hCompletionPort == NULL)
ErrorAbort("Could not create completion port");
cout << "Completion Port created\n";
//Create threads
CreateThreads(ulProcessors);
cout << "Threads created\n";
//Create socket
AcceptorSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
addrinfo *final, hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE;
if(getaddrinfo(NULL,"12345", &hints, &final))
ErrorAbort("Could not retrieve address information");
if(bind(AcceptorSock,final->ai_addr, final->ai_addrlen))
ErrorAbort("Could not bind socket");
freeaddrinfo(final);
cout << "Acceptor socket created and bound\nStarting to listen on the acceptor socket\n";
if(listen(AcceptorSock, 2))
ErrorAbort("Can´t listen on the socket");
//Add acceptor socket file handle to be observed by the completion port
if(CreateIoCompletionPort((HANDLE)AcceptorSock, hCompletionPort, NEW_CONNECTION, 0) != hCompletionPort)
ErrorAbort("A new completion port has been created instead of using the existing one");
cout << "Acceptor socket associated with the completion port\n";
ResumeThreads(2);
char lpOutputBuf[1024];
int outBufLen = 1024;
DWORD dwBytes;
OVERLAPPED over;
SOCKET newSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
while(true)
{
memset(&over, 0, sizeof(over));
if(AcceptEx(AcceptorSock, newSock, lpOutputBuf, outBufLen - ((sizeof(sockaddr_in) + 16) * 2), sizeof(sockaddr_in)+16, sizeof(sockaddr_in)+16, &dwBytes, &over) == FALSE)
{
int x = WSAGetLastError();
if( x != WSA_IO_PENDING)
ErrorAbort("Could not acceptex a new connection");
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您代码中的问题是这样的:
AcceptEx函数的第二个参数(在本例中为newSock)必须是未连接且未绑定的套接字,那么当新连接到达时,newSock参数将是无效参数(因为现在已连接),为了避免这种情况,必须创建一个新的套接字句柄,但循环必须等到新连接到达,为此必须使用 WSAEVENT。首先必须使用函数WSAEventSelect将FD_ACCEPT网络事件与WSAEVENT关联起来,这必须在创建AcceptThread之前完成:
AcceptThread然后调用AcceptEx函数并等待新连接,当新连接到达newSock时添加到完成端口并创建一个新的套接字,该线程仅具有接受连接所需的元素:
如果任何主体需要更多信息,此链接可能会很有用:
http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedscalableapp6b.html
http://www.codeproject.com/KB/IP/SimpleIOCPApp.aspx
http://msdn.microsoft.com/en-us/magazine/cc302334.aspx
Te problem in your code is this:
The second parameter of the AcceptEx Function (in this case newSock) must be a unconnected and unbound socket, then when a new connection arrives the newSock parameter will be an invalid parameter (because now is connected), to avoid this a New Socket Handle must be created, but the loop must wait until the new connection arrives, to do this a WSAEVENT must be use. The first the function WSAEventSelect must be used to associate the FD_ACCEPT Network event with the WSAEVENT, this mus be done before the creation of the AcceptThread:
The AcceptThread Then Call The AcceptEx Function and Wait for a New Connection, when a new connection arrives the newSock is Added to the Completion port and a new Socket is created, this thread have only the elements required to accept connections:
If any body needs more information this links could be useful:
http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedscalableapp6b.html
http://www.codeproject.com/KB/IP/SimpleIOCPApp.aspx
http://msdn.microsoft.com/en-us/magazine/cc302334.aspx
应使用
WSASocket
而不是socket
,并且在创建套接字时应传递WSA_FLAG_OVERLAPPED
标志。should use
WSASocket
rather thansocket
and you should pass theWSA_FLAG_OVERLAPPED
flag when creating the socket.