IOCP模型Demo
#include <winsock2.h> #include <stdio.h> #include <process.h> #include <time.h> #pragma comment(lib,"ws2_32") #define DEFAULT_BUFLEN 1024 typedef struct { OVERLAPPED Overlapped; WSABUF DataBuf; CHAR Buffer[DEFAULT_BUFLEN]; DWORD BytesRECV; }PER_IO_DATA,*LPPER_IO_DATA; typedef struct { SOCKET Socket; }PER_HANDLE_DATA,*LPPER_HANDLE_DATA; DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID); int main() { SOCKADDR_IN InternetAddr; SOCKET ServerSocket = INVALID_SOCKET; SOCKET AcceptSocket = INVALID_SOCKET; HANDLE CompletionPort; SYSTEM_INFO SystemInfo; PER_HANDLE_DATA a; PER_IO_DATA b; LPPER_HANDLE_DATA PerHandleData; LPPER_IO_DATA PerIoData; DWORD RecvBytes; DWORD Flags; DWORD ThreadID; WSADATA wsaData; DWORD Ret; int iResult; PerIoData = &b; PerHandleData =&a; if ((CompletionPort=CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,8)) == NULL) { printf("CreateIoCompletionPort err!\n"); return -1; } GetSystemInfo(&SystemInfo); for (int i=0;i<(SystemInfo.dwNumberOfProcessors)*2;i++)//创建工作线程循环 { HANDLE ThreadHandle; if ((ThreadHandle = CreateThread(NULL,0,ServerWorkerThread,(LPVOID)&CompletionPort,0,&ThreadID)) == NULL) { printf("创建工作线程i 失败"); return -1; } CloseHandle(ThreadHandle); } if ((Ret = WSAStartup(0x0202,&wsaData)) != 0) { printf("初始化失败"); return -1; } ServerSocket = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED); if (ServerSocket == INVALID_SOCKET) { printf("WSASocket() failed with error %d\n",WSAGetLastError()); return -1; } InternetAddr.sin_family = AF_INET; InternetAddr.sin_addr.s_addr=htonl(INADDR_ANY); InternetAddr.sin_port = htons(9000); iResult = bind(ServerSocket,(PSOCKADDR)&InternetAddr,sizeof(InternetAddr)); if (iResult == SOCKET_ERROR) { printf("bind失败"); return -1; } if (listen(ServerSocket,5)==SOCKET_ERROR) { printf("listen失败"); } printf("TCP server 开始"); sockaddr_in addrClient; int addrClientlen = sizeof(sockaddr_in); while (TRUE) { AcceptSocket = WSAAccept(ServerSocket,(sockaddr *)&addrClient,&addrClientlen,NULL,0); if (AcceptSocket == SOCKET_ERROR) { printf("WSAAccept() 失败"); return -1; } // PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR,sizeof(LPPER_HANDLE_DATA)); if (PerHandleData == NULL) { printf("GlobalAlloc 失败"); return -1; } PerHandleData->Socket =AcceptSocket; if (CreateIoCompletionPort((HANDLE)AcceptSocket,CompletionPort,(DWORD)PerHandleData,0) == NULL) { printf("CreateIoCompletionPort 失败"); return -1; } PerIoData = (LPPER_IO_DATA)GlobalAlloc(GPTR,sizeof(PER_IO_DATA)); if (PerHandleData == NULL) { printf("GlobalAlloc 失败"); return -1; } ZeroMemory(&(PerIoData->Overlapped),sizeof(OVERLAPPED)); PerIoData->BytesRECV = (DWORD)0; PerIoData->DataBuf.len = DEFAULT_BUFLEN; PerIoData->DataBuf.buf = PerIoData->Buffer; Flags = 0; iResult = WSARecv(AcceptSocket,&(PerIoData->DataBuf),1,&RecvBytes,&Flags,&(PerIoData->Overlapped),NULL); if (iResult == SOCKET_ERROR) { if (WSAGetLastError()!=ERROR_IO_PENDING) { printf("wsarecv 错误"); return -1; } } } return 0; } DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID) { HANDLE CompletionPort = *(HANDLE*)CompletionPortID; DWORD BytesTransferred; LPPER_HANDLE_DATA PerHandleData; LPPER_IO_DATA PerIoData; DWORD RecvBytes; DWORD Flags; int iResult; while(true) { if (GetQueuedCompletionStatus(CompletionPort,&BytesTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED *)&PerIoData,INFINITE) == 0) { printf("GetQueuedCompletionStatus 失败"); return 0; } if (BytesTransferred == 0) { printf("Closing socket %d\n",PerHandleData->Socket); if (closesocket(PerHandleData->Socket) == SOCKET_ERROR) { printf("close err"); return 0; } GlobalFree(PerHandleData); GlobalFree(PerIoData); continue; } if (PerIoData->BytesRECV == 0) { PerIoData->BytesRECV = BytesTransferred; } printf("\nBytes received: %d\n",BytesTransferred); PerIoData->BytesRECV = 0; Flags = 0; ZeroMemory(&(PerIoData->Overlapped),sizeof(OVERLAPPED)); PerIoData->DataBuf.len = DEFAULT_BUFLEN; PerIoData->DataBuf.buf = PerIoData->Buffer; iResult =WSARecv(PerHandleData->Socket,&(PerIoData->DataBuf),1,&RecvBytes,&Flags,&(PerIoData->Overlapped),NULL); if (iResult == SOCKET_ERROR) { if (WSAGetLastError()!= ERROR_IO_PENDING) { printf("WSARecv err:%d",WSAGetLastError()); return 0; } } printf("%s",PerIoData->DataBuf.buf); return 0; } }
本文作者:StanWind
文章标题: IOCP模型Demo
本文地址:https://www.stanwind.com/post/16
版权声明:若无注明,本文皆为“Make it Better”原创,转载请保留文章出处。
本文地址:https://www.stanwind.com/post/16
版权声明:若无注明,本文皆为“Make it Better”原创,转载请保留文章出处。
相关文章