windows下高效网络通讯 IOCP

  • P2_939440
    了解作者
  • 8.4KB
    文件大小
  • rar
    文件格式
  • 0
    收藏次数
  • VIP专享
    资源类型
  • 0
    下载次数
  • 2022-04-21 02:45
    上传日期
对IOCP做了很好的处理,良好的通讯机制和SOCKET io的预分配和预投递机制
IOCP.rar
  • IOCP.CPP
    25.1KB
  • IOCP.H
    4.6KB
内容介绍
////////////////////////////////////////////////// // IOCP.cpp文件 #include "iocp.h" #pragma comment(lib, "WS2_32.lib") CIOCPServer::CIOCPServer() { // 列表 m_pFreeBufferList = NULL; m_pFreeContextList = NULL; m_pPendingAccepts = NULL; m_pConnectionList = NULL; m_nFreeBufferCount = 0; m_nFreeContextCount = 0; m_nPendingAcceptCount = 0; m_nCurrentConnection = 0; ::InitializeCriticalSection(&m_FreeBufferListLock); ::InitializeCriticalSection(&m_FreeContextListLock); ::InitializeCriticalSection(&m_PendingAcceptsLock); ::InitializeCriticalSection(&m_ConnectionListLock); // Accept请求 m_hAcceptEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); m_hRepostEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); m_nRepostCount = 0; m_nPort = 4567; m_nInitialAccepts = 10; m_nInitialReads = 4; m_nMaxAccepts = 100; m_nMaxSends = 20; m_nMaxFreeBuffers = 200; m_nMaxFreeContexts = 100; m_nMaxConnections = 2000; m_hListenThread = NULL; m_hCompletion = NULL; m_sListen = INVALID_SOCKET; m_lpfnAcceptEx = NULL; m_lpfnGetAcceptExSockaddrs = NULL; m_bShutDown = FALSE; m_bServerStarted = FALSE; // 初始化WS2_32.dll WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 2); ::WSAStartup(sockVersion, &wsaData); } CIOCPServer::~CIOCPServer() { Shutdown(); if(m_sListen != INVALID_SOCKET) ::closesocket(m_sListen); if(m_hListenThread != NULL) ::CloseHandle(m_hListenThread); ::CloseHandle(m_hRepostEvent); ::CloseHandle(m_hAcceptEvent); ::DeleteCriticalSection(&m_FreeBufferListLock); ::DeleteCriticalSection(&m_FreeContextListLock); ::DeleteCriticalSection(&m_PendingAcceptsLock); ::DeleteCriticalSection(&m_ConnectionListLock); ::WSACleanup(); } /////////////////////////////////// // 自定义帮助函数 CIOCPBuffer *CIOCPServer::AllocateBuffer(int nLen) { CIOCPBuffer *pBuffer = NULL; if(nLen > BUFFER_SIZE) return NULL; // 为缓冲区对象申请内存 ::EnterCriticalSection(&m_FreeBufferListLock); if(m_pFreeBufferList == NULL) // 内存池为空,申请新的内存 { pBuffer = (CIOCPBuffer *)::HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CIOCPBuffer) + BUFFER_SIZE); } else // 从内存池中取一块来使用 { pBuffer = m_pFreeBufferList; m_pFreeBufferList = m_pFreeBufferList->pNext; pBuffer->pNext = NULL; m_nFreeBufferCount --; } ::LeaveCriticalSection(&m_FreeBufferListLock); // 初始化新的缓冲区对象 if(pBuffer != NULL) { pBuffer->buff = (char*)(pBuffer + 1); pBuffer->nLen = nLen; } return pBuffer; } void CIOCPServer::ReleaseBuffer(CIOCPBuffer *pBuffer) { ::EnterCriticalSection(&m_FreeBufferListLock); if(m_nFreeBufferCount <= m_nMaxFreeBuffers) // 将要释放的内存添加到空闲列表中 { memset(pBuffer, 0, sizeof(CIOCPBuffer) + BUFFER_SIZE); pBuffer->pNext = m_pFreeBufferList; m_pFreeBufferList = pBuffer; m_nFreeBufferCount ++ ; } else // 已经达到最大值,真正的释放内存 { ::HeapFree(::GetProcessHeap(), 0, pBuffer); } ::LeaveCriticalSection(&m_FreeBufferListLock); } CIOCPContext *CIOCPServer::AllocateContext(SOCKET s) { CIOCPContext *pContext; // 申请一个CIOCPContext对象 ::EnterCriticalSection(&m_FreeContextListLock); if(m_pFreeContextList == NULL) { pContext = (CIOCPContext *) ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CIOCPContext)); ::InitializeCriticalSection(&pContext->Lock); } else { // 在空闲列表中申请 pContext = m_pFreeContextList; m_pFreeContextList = m_pFreeContextList->pNext; pContext->pNext = NULL; m_nFreeBufferCount --; } ::LeaveCriticalSection(&m_FreeContextListLock); // 初始化对象成员 if(pContext != NULL) { pContext->s = s; } return pContext; } void CIOCPServer::ReleaseContext(CIOCPContext *pContext) { if(pContext->s != INVALID_SOCKET) ::closesocket(pContext->s); // 首先释放(如果有的话)此套节字上的没有按顺序完成的读I/O的缓冲区 CIOCPBuffer *pNext; while(pContext->pOutOfOrderReads != NULL) { pNext = pContext->pOutOfOrderReads->pNext; ReleaseBuffer(pContext->pOutOfOrderReads); pContext->pOutOfOrderReads = pNext; } ::EnterCriticalSection(&m_FreeContextListLock); if(m_nFreeContextCount <= m_nMaxFreeContexts) // 添加到空闲列表 { // 先将关键代码段变量保存到一个临时变量中 CRITICAL_SECTION cstmp = pContext->Lock; // 将要释放的上下文对象初始化为0 memset(pContext, 0, sizeof(CIOCPContext)); // 再放会关键代码段变量,将要释放的上下文对象添加到空闲列表的表头 pContext->Lock = cstmp; pContext->pNext = m_pFreeContextList; m_pFreeContextList = pContext; // 更新计数 m_nFreeContextCount ++; } else { ::DeleteCriticalSection(&pContext->Lock); ::HeapFree(::GetProcessHeap(), 0, pContext); } ::LeaveCriticalSection(&m_FreeContextListLock); } void CIOCPServer::FreeBuffers() { // 遍历m_pFreeBufferList空闲列表,释放缓冲区池内存 ::EnterCriticalSection(&m_FreeBufferListLock); CIOCPBuffer *pFreeBuffer = m_pFreeBufferList; CIOCPBuffer *pNextBuffer; while(pFreeBuffer != NULL) { pNextBuffer = pFreeBuffer->pNext; if(!::HeapFree(::GetProcessHeap(), 0, pFreeBuffer)) { #ifdef _DEBUG ::OutputDebugString(" FreeBuffers释放内存出错!"); #endif // _DEBUG break; } pFreeBuffer = pNextBuffer; } m_pFreeBufferList = NULL; m_nFreeBufferCount = 0; ::LeaveCriticalSection(&m_FreeBufferListLock); } void CIOCPServer::FreeContexts() { // 遍历m_pFreeContextList空闲列表,释放缓冲区池内存 ::EnterCriticalSection(&m_FreeContextListLock); CIOCPContext *pFreeContext = m_pFreeContextList; CIOCPContext *pNextContext; while(pFreeContext != NULL) { pNextContext = pFreeContext->pNext; ::DeleteCriticalSection(&pFreeContext->Lock); if(!::HeapFree(::GetProcessHeap(), 0, pFreeContext)) { #ifdef _DEBUG ::OutputDebugString(" FreeBuffers释放内存出错!"); #endif // _DEBUG break; } pFreeContext = pNextContext; } m_pFreeContextList = NULL; m_nFreeContextCount = 0; ::LeaveCriticalSection(&m_FreeContextListLock); } BOOL CIOCPServer::AddAConnection(CIOCPContext *pContext) { // 向客户连接列表添加一个CIOCPContext对象 ::EnterCriticalSection(&m_ConnectionListLock); if(m_nCurrentConnection <= m_nMaxConnections) { // 添加到表头 pContext->pNext = m_pConnectionList; m_pConnectionList = pContext; // 更新计数 m_nCurrentConnection ++; ::LeaveCriticalSection(&m_ConnectionListLock); return TRUE; } ::LeaveCriticalSection(&m_ConnectionListLock); return FALSE; } void CIOCPServer::CloseAConnection(CIOCPContext *pContext) { // 首先从列表中移除要关闭的连接 ::EnterCriticalSection(&m_ConnectionListLock); CIOCPContext* pTest = m_pConnectionList; if(pTest == pContext) { m_pConnectionList = pContext->pNext; m_nCurrentConnection --; } else { while(pTest != NULL && pTest->pNext != pContext) pTest = pTest->pNext; if(pTest != NULL) { pTest->pNext = pContext->pNext; m_nCurrentConnection --; } } ::LeaveCriticalSection(&m_ConnectionListLock); // 然后关闭客户套节字 ::EnterCriticalSection(&pContext->Lock); if(pContext->s != INVALID_SOCKET) { ::closesocket(pContext->s); pContext->s = INVALID_SOCKET; } pContext->bClosing = TRUE; ::LeaveCriticalSection(&pContext->Lock); } void CIOCPServer::CloseAllConnections() { // 遍历整个连接列表,关闭所有的客户套节字 ::EnterCriticalSection(&m_ConnectionListLock); CIOCPContext *pContext = m_pConnectionList; while(pContext != NULL) { ::EnterCriticalSection(&pContext->Lock); if(pContext->s != INVALID_SOCKET) { ::closesocket(pContext->s); pContext->s = INVALID_SOCKET; } pContext->bClosing = TRUE; ::LeaveCriticalSection(&pContext->Lock); pContext = pContext->pNext; } m_pConnectionList = NULL; m_nCurrentConnection = 0; ::LeaveCriticalSectio
评论
    相关推荐
    • windows系统解析
      1.windows XP系统内核文件分析(全) 2.Windows2000XP系统文件夹详解 3.Windows下的EXE文件解析 4.WINDOWS常见文件夹完全解析 5.Windows文件解析——CWINDOWSsystem32driversetchosts 6.Windows系统文件解析 7.对...
    • Windows 基础
      Windows API 基础 Windows API 基础 Windows API 基础 Windows API 基础 Windows API 基础
    • Windows 3.1
      Windows 3.1 网站 下载 简单的
    • windows 计算器
      windows 自带的计算器。解压到c:\windows\system32下。直接windows键+r 调用calc命令运行。
    • windows95
      Windows95的
    • windows shell
      windows shell的中文翻译,对windows程序员很有用
    • Windows file
      Windows file Windows file
    • windows 窗体
      加载子窗体的源码,windows 窗体。
    • windows清理
      Microsoft 已更新了 Windows Installer 清理实用工具(Windows Installer CleanUp Utility ).利用 Windows Installer 清理实用工具,可以删除程序的 Windows Installer 配置信息.如果您遇到安装(安装程序)问题,可能...
    • windows api
      windows api资源,包括:Windows高级编程源代码 MFC中文帮助 vfp_api Windows程序设计