Пример реализации модели портов завершения.
#include <iostream.h> #include <Winsock2.h> #pragma comment(lib, "ws2_32.lib") void ErrorView(); DWORD WINAPI MainServThread(LPVOID CompletionPort); SOCKET sock; #define RECV 1001 #define SEND 1002 typedef struct { OVERLAPPED Overlapped; WSABUF DataBuf; CHAR Buffer[1024]; int IO_Type; } io_str, * lp_io_str; typedef struct { SOCKET Socket; } io_handle_data, * lp_io_handle_data; int main() { WSADATA wsaData; if(!WSAStartup(0x0202,&wsaData)) { HANDLE io_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0); if(io_port != NULL) { SYSTEM_INFO SystemInfo;GetSystemInfo(&SystemInfo); for(int i = 0; i < (int)SystemInfo.dwNumberOfProcessors ; i++) { HANDLE MainThread; DWORD dwID; if((MainThread = CreateThread(NULL,0, MainServThread, (LPVOID)io_port,0, &dwID)) == NULL) {cout<<"Error CreateThread"<<endl;return -1;} CloseHandle(MainThread); } SOCKET sockList; if((sockList = WSASocket(AF_INET, SOCK_STREAM,0, NULL,0, WSA_FLAG_OVERLAPPED)) != INVALID_SOCKET) { SOCKADDR_IN InetAddr; InetAddr.sin_family = AF_INET; InetAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); InetAddr.sin_port = htons(4004); if(bind(sockList,(PSOCKADDR)&InetAddr,sizeof(InetAddr)) != SOCKET_ERROR) { if(!(listen(sockList,SOMAXCONN))) { SOCKET Accept; while(TRUE) { if ((Accept = WSAAccept(sockList,NULL,NULL,NULL,0)) != SOCKET_ERROR) { cout<<"Accept: "<<Accept<<endl; lp_io_handle_data sock; sock = (lp_io_handle_data)GlobalAlloc(GPTR,sizeof(io_handle_data)); if(sock) { sock->Socket = Accept; if(CreateIoCompletionPort((HANDLE)Accept,io_port,(DWORD)sock,0) != NULL) { lp_io_str io_data; if((io_data = (lp_io_str)GlobalAlloc(GPTR,sizeof(io_str))) != NULL) { ZeroMemory(&(io_data->Overlapped),sizeof(OVERLAPPED)); io_data->DataBuf.len = 1024; io_data->DataBuf.buf = io_data->Buffer; io_data->IO_Type = RECV; DWORD dwRecv,dwFlags = 0; if(WSARecv(Accept, &(io_data->DataBuf), 1,&dwRecv, &dwFlags, &(io_data->Overlapped), NULL) != SOCKET_ERROR) { cout<<"WSARecv..."<<endl;} else {if(WSAGetLastError() != ERROR_IO_PENDING) {cout<<"Error WSARecv..."<<endl;ErrorView();return -1;}} }else{cout<<"Error GlobalAlloc(2)"<<endl;} }else{cout<<"Error CreateIoCompletionPort(2)"<<endl;} }else{cout<<"Error GlobalAlloc"<<endl;} }else{cout<<"Error WSAAccept..."<<endl;ErrorView();return -1;} }//while(TRUE) }else{cout<<"Error listen..."<<endl;ErrorView();} }else{cout<<"Error bind..."<<endl;ErrorView();} }else{cout<<"Error WSASocket..."<<endl;ErrorView();} }else{cout<<"Error CreateIoCompletionPort..."<<endl;} }else{cout<<"Error WSAStartup..."<<endl;ErrorView();} WSACleanup(); return 0; } /*************************************************************/ //Iioie ii?oa caaa?oaiey /*************************************************************/ DWORD WINAPI MainServThread(LPVOID CompletionPort) { HANDLE h_io_port = (HANDLE)CompletionPort; DWORD dwBytes; lp_io_str io_data; lp_io_handle_data sock; while(TRUE) { if(GetQueuedCompletionStatus(h_io_port, &dwBytes, (LPDWORD)&sock, (LPOVERLAPPED *)&io_data, INFINITE) == 0) {cout<<"Error...(1)"<<endl;} if(dwBytes == 0) { if(closesocket(sock->Socket) != SOCKET_ERROR) {cout<<"closesocket: "<<sock->Socket<<endl;} else{cout<<"error closesocket..."<<endl;ErrorView();} GlobalFree(io_data); GlobalFree(sock); continue; } if(io_data->IO_Type == SEND) { cout<<"SEND: "<<io_data->Buffer<<endl; } if(io_data->IO_Type == RECV) { cout<<io_data->Buffer<<endl; if(io_data->Buffer[0] == '0') { ZeroMemory(&(io_data->Overlapped),sizeof(OVERLAPPED)); ZeroMemory(&(io_data->Buffer),sizeof(1024)); io_data->DataBuf.len = 1024; strcpy(io_data->Buffer,"ok"); io_data->DataBuf.buf = io_data->Buffer; io_data->IO_Type = SEND; DWORD dwSend; if (WSASend(sock->Socket, &(io_data->DataBuf), 1,&dwSend,0, &(io_data->Overlapped), NULL) == SOCKET_ERROR) {if(WSAGetLastError()!= ERROR_IO_PENDING) {cout<<"Error WSASend..."<<endl;ErrorView();return -1;}} continue; }//if } ZeroMemory(&(io_data->Overlapped),sizeof(OVERLAPPED)); ZeroMemory(&(io_data->Buffer),sizeof(1024)); io_data->DataBuf.len = 1024; io_data->DataBuf.buf = io_data->Buffer; io_data->IO_Type = RECV; DWORD dwRecv,dwFlags = 0; if(WSARecv(sock->Socket, &(io_data->DataBuf),1, &dwRecv,&dwFlags, &(io_data->Overlapped), NULL) == SOCKET_ERROR) {if(WSAGetLastError()!= ERROR_IO_PENDING) {cout<<"Error WSARecv..."<<endl;ErrorView();return -1;}} } return 0; } /*************************************************************/ //Ooieoey auaiaa ioeaie... /*************************************************************/ void ErrorView() { LPVOID lpMsgBuf = NULL; FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, NULL,WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); CharToOem((LPTSTR)lpMsgBuf,(LPTSTR)lpMsgBuf); cout<<(LPCTSTR)lpMsgBuf<<endl; LocalFree(lpMsgBuf); }