Те проблема в вашем коде заключается в следующем:
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");
}
}
Второй параметр функции AcceptEx (в данном случае newSock) должен быть неподключенным и несвязанным сокетом, а затем, когда приходит новое соединение, параметр newSock будет недопустимым параметром (потому что теперь подключен), чтобы избежать этого New Должен быть создан Socket Handle, но цикл должен дождаться прибытия нового соединения, для этого должен использоваться WSAEVENT. Сначала необходимо использовать функцию WSAEventSelect, чтобы связать сетевое событие FD_ACCEPT с WSAEVENT, это необходимо сделать до создания AcceptThread:
g_ev = WSACreateEvent();
if (WSA_INVALID_EVENT == g_ev)
ErrorAbort("Error occurred while WSACreateEvent()";
if (SOCKET_ERROR == WSAEventSelect(AcceptorSock, g_ev, FD_ACCEPT))
{
WSACloseEvent(g_ev);
ErrorAbort("Error occurred while WSAEventSelect().");
}
AcceptThread, затем вызов функции AcceptEx и ожидание нового соединения, когда новое соединение приходит, в порт завершения добавляется newSock, и создается новый сокет, этот поток имеет только элементы, необходимые для приема соединений:
DWORD WINAPI AcceptThread(LPVOID lParam)
{
SOCKET AcceptorSock = (SOCKET)lParam, new;
SOCKET newSock;
OVERLAPPED over;
DWORD wr;
memset(&over, 0, sizeof(over));
do
{
newSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
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 != ERROR_IO_PENDING)
{
cout << "Could not acceptex a new connection" << endl;
return 1;
}
else
{
if (WSA_WAIT_TIMEOUT != (wr = WSAWaitForMultipleEvents(1, &g_ev, FALSE, INFINITE, FALSE)))
{
WSAEnumNetworkEvents(AcceptorSock, g_ev, &WSAEvents);
if ((WSAEvents.lNetworkEvents & FD_ACCEPT) && (0 == WSAEvents.iErrorCode[FD_ACCEPT_BIT]))
{
if (CreateIoCompletionPort(newSock, hCompletionPort, 0, 0) == NULL)
{
cout << "Error CreateIoCompletionPort" << endl;
return 2;
}
WSAResetEvent(g_ev);
}
}
}
}
}while(wr != WSA_WAIT_EVENT_0);
}
Если кому-то нужно больше информации, эти ссылки могут быть полезны:
http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancedscalableapp6b.html
http://www.codeproject.com/KB/IP/SimpleIOCPApp.aspx
http://msdn.microsoft.com/en-us/magazine/cc302334.aspx