IOCP例子二
来源:互联网 发布:win10ie无法下载软件 编辑:程序博客网 时间:2024/06/03 16:10
#include <winsock2.h>#include <Mswsock.h>#include <stdio.h>#include <windows.h>#include <assert.h>#include <list>#pragma comment(lib, "ws2_32.lib")#pragma comment(lib,"Mswsock.lib")using namespace std;LONG volatileg_ThreadNum;//线程数目HANDLEg_hCompletion;// SOCKETg_socket;//sock #defineBUFFER_SIZE20480//最大缓冲enum IO_TYPE {IO_TYPE_ACCEPT,//网络连接IO_TYPE_READ,//网络读取IO_TYPE_WRITE,//网络写入IO_TYPE_UNKNOWN//无效类型};#pragma pack(1)struct OverLappedEx {OVERLAPPEDm_OLap;IO_TYPEm_IOType;//IO请求类型charm_szBuf[BUFFER_SIZE];//接收缓冲OverLappedEx(IO_TYPE ioType){ZeroMemory(&m_OLap, sizeof(OVERLAPPED));ZeroMemory(m_szBuf, BUFFER_SIZE);m_IOType = ioType;}};struct PerSocketData {SOCKET m_Socket;SOCKET m_AccSocket;PerSocketData(){m_Socket = INVALID_SOCKET;m_AccSocket = INVALID_SOCKET;}};#pragma pack()list <PerSocketData *> g_ArrSocketData;list <OverLappedEx *> g_ArrOverLapEx;PerSocketData *AssignSockToCompletionPort(SOCKET tSocket){assert(tSocket != INVALID_SOCKET);PerSocketData *pSockData = new PerSocketData();pSockData->m_Socket = tSocket;g_ArrSocketData.push_back(pSockData);CreateIoCompletionPort((HANDLE)tSocket, g_hCompletion, (ULONG_PTR)pSockData, 0);return pSockData;}BOOL PostAccept(PerSocketData *pSockData){DWORD dwBytesRecv = 0;assert(pSockData != NULL);OverLappedEx *m_pOverLap = new OverLappedEx(IO_TYPE_ACCEPT);g_ArrOverLapEx.push_back(m_pOverLap);pSockData->m_AccSocket = WSASocket(AF_INET , SOCK_STREAM , IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);BOOL bRet = AcceptEx(pSockData->m_Socket, pSockData->m_AccSocket, m_pOverLap->m_szBuf, 0, sizeof(sockaddr_in)+16, sizeof(sockaddr_in)+16, &dwBytesRecv, &m_pOverLap->m_OLap);if (!bRet){if (WSAGetLastError() != WSA_IO_PENDING) {return FALSE;}}return TRUE;}BOOL PostRecv(PerSocketData *pSockData){assert(pSockData != NULL);WSABUF wsaBuf = {0};OverLappedEx *m_pOverLap = new OverLappedEx(IO_TYPE_READ);g_ArrOverLapEx.push_back(m_pOverLap);wsaBuf.buf = m_pOverLap->m_szBuf;wsaBuf.len = BUFFER_SIZE;DWORD dwBytesRecv = 0, dwFlags = 0;int iRet = WSARecv(pSockData->m_Socket, &wsaBuf, 1, &dwBytesRecv, &dwFlags, &(m_pOverLap->m_OLap), NULL);if (iRet != NO_ERROR){if (WSAGetLastError() != WSA_IO_PENDING){return FALSE;}}return TRUE;}DWORD WINAPI ServerThread(LPVOID lpParam){//参数效验assert(lpParam!=NULL);if (lpParam==NULL)return FALSE;//定义变量 HANDLE hCompletion = (HANDLE)lpParam;OverLappedEx *pOverLaps = NULL;PerSocketData *pPerSockData = NULL;DWORD dwTrans = 0;BOOL bOK=FALSE; InterlockedIncrement(&g_ThreadNum);while(TRUE){// 在关联到此完成端口的所有套节字上等待I/O完成bOK= GetQueuedCompletionStatus(hCompletion, &dwTrans, (LPDWORD)&pPerSockData, (LPOVERLAPPED*)&pOverLaps, INFINITE);//收到关闭通知if (pPerSockData==NULL || pOverLaps==NULL) break;// 在此套节字上有错误发生if(bOK==FALSE)continue;// 套节字被对方关闭if(dwTrans == 0 && pOverLaps!=NULL &&(pOverLaps->m_IOType == IO_TYPE_READ || pOverLaps->m_IOType == IO_TYPE_WRITE)){closesocket(pPerSockData->m_Socket);g_ArrSocketData.remove(pPerSockData);g_ArrOverLapEx.remove(pOverLaps);delete pPerSockData;delete pOverLaps;pPerSockData=NULL;pOverLaps=NULL;continue;}switch(pOverLaps->m_IOType){case IO_TYPE_READ://网络读取{PostRecv(pPerSockData);printf("收到客户端数据:%s\n",pOverLaps->m_szBuf);DWORD dwSend = 0;OverLappedEx *pOverLapEx = NULL;pOverLapEx = new OverLappedEx(IO_TYPE_WRITE);memcpy_s(pOverLapEx->m_szBuf, BUFFER_SIZE, "这是服务端发送的消息", ARRAYSIZE("这是服务端发送的消息"));WSABUF wsaBuf = {0};wsaBuf.buf = pOverLapEx->m_szBuf;wsaBuf.len = ARRAYSIZE("这是服务端发送的消息");g_ArrOverLapEx.push_back(pOverLapEx);//针对单个客户端发//WSASend(pPerSockData->m_Socket, &wsaBuf, 1, &dwSend, 0, &(pOverLapEx->m_OLap), NULL);//所有客户端群发list<PerSocketData*>::const_iterator cIterSocke; for (cIterSocke = g_ArrSocketData.begin(); cIterSocke != g_ArrSocketData.end(); cIterSocke++) {//过滤自己if ((*cIterSocke)->m_Socket==g_socket)continue;WSASend((*cIterSocke)->m_Socket, &wsaBuf, 1, &dwSend, 0, &(pOverLapEx->m_OLap), NULL);}g_ArrOverLapEx.remove(pOverLaps);if (pOverLaps){delete pOverLaps;pOverLaps =NULL;}}break;case IO_TYPE_WRITE:{g_ArrOverLapEx.remove(pOverLaps);if (pOverLaps){delete pOverLaps;pOverLaps =NULL;}}break;case IO_TYPE_ACCEPT:{if (pPerSockData->m_AccSocket == INVALID_SOCKET)continue;PerSocketData *pData = AssignSockToCompletionPort(pPerSockData->m_AccSocket);PostRecv(pData);PostAccept(pPerSockData);g_ArrOverLapEx.remove(pOverLaps);if (pOverLaps){delete pOverLaps;pOverLaps =NULL;}}break;default:break;}}InterlockedDecrement(&g_ThreadNum);return 0;}//启动服务DWORD ThreadProc( LPVOID lpParameter){//设置变量g_ThreadNum=0;int nPort = 4567;//创建完成端口对象g_hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);// 创建监听套节字g_socket = WSASocket(AF_INET , SOCK_STREAM , IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);assert(g_socket!=INVALID_SOCKET);if (g_socket==INVALID_SOCKET)return FALSE;//绑定端口SOCKADDR_IN ServerAddr;ServerAddr.sin_family = AF_INET;ServerAddr.sin_port = ntohs(nPort);ServerAddr.sin_addr.S_un.S_addr = INADDR_ANY;if (bind(g_socket, (sockaddr*)&ServerAddr, sizeof(ServerAddr))==SOCKET_ERROR){assert(FALSE);return FALSE;}//监听listen(g_socket, SOMAXCONN);//关联套接字PerSocketData *pSockData = AssignSockToCompletionPort(g_socket);//队列工作项在线程池中的工作线程QueueUserWorkItem(ServerThread, g_hCompletion, WT_EXECUTELONGFUNCTION);PostAccept(pSockData);return TRUE;}int main(void){// 初始化WS2_32.dllWSADATA wsaData;WORD sockVersion = MAKEWORD(2, 0);WSAStartup(sockVersion, &wsaData);//启动服务CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ThreadProc,NULL,NULL,NULL);getchar();//清理线程工作while(g_ThreadNum > 0){PostQueuedCompletionStatus(g_hCompletion, 0, 0, NULL);Sleep(100);} list<PerSocketData*>::const_iterator cIterSocke; for (cIterSocke = g_ArrSocketData.begin(); cIterSocke != g_ArrSocketData.end(); cIterSocke++) { closesocket((*cIterSocke)->m_Socket); delete *cIterSocke; } g_ArrSocketData.clear(); list<OverLappedEx*>::const_iterator cIter; for (cIter = g_ArrOverLapEx.begin(); cIter != g_ArrOverLapEx.end(); cIter++) { delete *cIter; } g_ArrOverLapEx.clear();CloseHandle(g_hCompletion); WSACleanup();return 0;}
0 0
- IOCP例子二
- IOCP例子
- IOCP例子
- IOCP例子
- iocp 例子
- iocp例子
- iocp例子
- IOCP二
- IOCP的例子
- 简单的iocp例子
- 一个IOCP 例子
- IOCP的例子
- IOCP的例子
- winsock IOCP收发例子
- 一个IOCP例子
- IOCP完整例子
- 简单IOCP例子
- IOCP完整例子
- PaletteDemoMaterial Design使用动态颜色
- 如何用正则表达式匹配包括换行符的任意字符?
- LeetCode 62. Unique Paths
- 2016"百度之星" - 初赛(Astar Round2A)解题报告
- Clime Cross GFW
- IOCP例子二
- 菜鸟的第一篇C博:希望成长
- ORA-01157 错误解决,原因DBWR锁定产生
- HDU 2571
- 如何解决Tomcat启动时重复出现Socket accept failed错误
- Android打造ListView万能适配器
- 60. Permutation Sequence
- Block如何避免self retain
- LINUX 新增的磁盘不建立分区,直接建立文件系统并挂载怎么办?