本文共 5313 字,大约阅读时间需要 17 分钟。
#pragma once#include#define IP_SIZE 32#define BUFFER_SIZE 1024#include #include enum SOCKET_STATE { ACCEPT = 1, SEND, RECV};typedef struct tagPLEData { SOCKET sSocket; CHAR szClientIP[IP_SIZE]; UINT uiClientPort; /*其他信息*/} PLEDATA, *LPPLEDATA;typedef struct tagIOData { OVERLAPPED oOverlapped; WSABUF wsBuffer; CHAR szBuffer[BUFFER_SIZE]; DWORD dSend; DWORD dRecv; SOCKET_STATE sState;} IOData, *LPIOData;typedef void (*ReadProc)(LPPLEDATA lpData, CHAR * RecvData);class Iocp {public: Iocp(const CHAR * host, UINT port); ~Iocp(); void SetThreadNums(); UINT GetThreadNums(); void SetPort(UINT port); UINT GetPort(); void Close(); static void ServerWorkThread(VOID * _this); void SetReadProc(VOID * lprFun);public: bool ListenEx(UINT backlog); ReadProc lpFun; HANDLE h_ComPlePort; static void AcceptEx(VOID * _this); UINT iThreadNums; bool bIsListen; SOCKADDR_IN m_SockAddr; SOCKET m_ListenSocketID; CHAR m_Host[IP_SIZE]; UINT m_Port;};
#include "Iocp.h"Iocp::Iocp(const CHAR * host, UINT port) { WSADATA wsaData; DWORD dwRet = WSAStartup(0x0202, &wsaData); if (0 != dwRet) { WSACleanup(); throw 1; } m_ListenSocketID = INVALID_SOCKET; memset(&m_SockAddr, 0, sizeof(SOCKADDR_IN)); memset(m_Host, 0, IP_SIZE); m_Port = 0; SYSTEM_INFO mySysInfo; GetSystemInfo(&mySysInfo); iThreadNums = mySysInfo.dwNumberOfProcessors * 2 + 1; bIsListen = true; strncpy_s(m_Host, host, IP_SIZE - 1); m_SockAddr.sin_family = AF_INET; m_SockAddr.sin_addr.s_addr = inet_addr(host); m_SockAddr.sin_port = htons(port); m_ListenSocketID = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED); if (m_ListenSocketID == INVALID_SOCKET) { throw 1; } setsockopt(m_ListenSocketID, SOL_SOCKET, SO_REUSEADDR, (const CHAR *) &opt, sizeof(opt)); if (ret != 0) { throw 1; } if (bind(m_ListenSocketID, (const struct sockaddr *) &m_SockAddr, sizeof(struct sockaddr)) == SOCKET_ERROR) { throw 1; } h_ComPlePort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); if (h_ComPlePort == NULL) { throw 1; } for (DWORD i = 0; i < (mySysInfo.dwNumberOfProcessors * 2 + 1); ++i) { _beginthread(Iocp::ServerWorkThread, 0, (VOID *) this); }}Iocp::~Iocp() { WSACleanup();}BOOL Iocp::ListenEx(UINT backlog) { if (listen(m_ListenSocketID, backlog) == SOCKET_ERROR) { return false; } if (-1 == _beginthread(Iocp::AcceptEx, 0, (VOID *) this)) { return false; } return true;}void Iocp::AcceptEx(VOID * _this) { SOCKET acSocket; DWORD dwRecvBytes; Iocp * pTemp = (Iocp *) _this; SOCKADDR_IN sAddr; UINT uiClientSize = sizeof(sAddr); while (true) { acSocket = WSAAccept(pTemp->m_ListenSocketID, (SOCKADDR *) &sAddr, &uiClientSize, NULL, 0); if (acSocket == SOCKET_ERROR) { return; } LPPLEDATA lpSocketData = (LPPLEDATA) malloc(sizeof(PLEDATA)); if (lpSocketData == NULL) { return; } lpSocketData->sSocket = acSocket; sprintf(lpSocketData->szClientIP, inet_ntoa(sAddr.sin_addr)); lpSocketData->uiClientPort = sAddr.sin_port; if (CreateIoCompletionPort((HANDLE) acSocket, pTemp->h_ComPlePort, (ULONG_PTR) lpSocketData, 0) == NULL) { return; } if (pTemp->bIsListen = false) { break; } LPIOData lpIoData = (LPIOData) malloc(sizeof(IOData)); if (lpIoData == NULL) { return; } ZeroMemory(lpIoData->oOverlapped, sizeof(lpIoData->oOverlapped)); lpIoData->dSend = 0; lpIoData->dRecv = 0; lpIoData->wsBuffer.len = BUFFER_SIZE; lpIoData->wsBuffer.buf = lpIoData->szBuffer; lpIoData->sState = SEND; if (WSARecv(acSocket, (WSABUF *) lpIoData->wsBuffer, 1, &dwRecvBytes, &flags, (OVERLAPPED *) lpIoData->oOverlapped, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != ERROR_IO_PENDING) { return; } } }}void Iocp::ServerWorkThread(VOID * _this) { Iocp * lpTemp = (Iocp *) _this; HANDLE hPlePort = (HANDLE) lpTemp->h_ComPlePort; DWORD dwBytes; LPPLEDATA lpPleData = NULL; LPIOData lpIoData = NULL; while (TRUE) { GetQueuedCompletionStatus(hPlePort, &dwBytes, (PULONG_PTR *) &lpPleData, (LPOVERLAPPED *) &lpIoData, INFINITE); if (dwBytes == 0 || lpIoData == NULL) { printf("there is a socket away\n"); free(lpPleData); free(lpIoData); continue; } lpIoData->dRecv = dwBytes; lpIoData->szBuffer[lpIoData->dRecv] = 0; lpTemp->lpFun(lpPleData, lpIoData->szBuffer); lpIoData->dRecv = 0; ZeroMemory(lpIoData->oOverlapped, sizeof(OVERLAPPED)); lpIoData->wsBuffer.len = BUFFER_SIZE; lpIoData->wsBuffer.buf = lpIoData->szBuffer; if (WSARecv(lpPleData->sSocket, (WSABUF *) lpIoData->wsBuffer, 1, &recvBytes, &dwFlag, (OVERLAPPED *) lpIoData->oOverlapped, NULL) == SOCKET_ERROR) { if (WSAGetLastError() != ERROR_IO_PENDING) { return; } } }}void Iocp::SetReadProc(VOID * lprFun) { lpFun = (ReadProc) lprFun;} 转载地址:http://iqojz.baihongyu.com/