//////////////////////////////////////////////////
// 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_nFreeContextCount --;
}
::LeaveCriticalSection(&m_FreeContextListLock);
// 初始化对象成员
if(pContext != NULL)
{
pContext->s = s;
pContext->lpBufBegin = pContext->lpBufEnd = pContext->arrayDataBuf;
}
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;
}
else
{
#ifdef _DEBUG
OutputDebugString(" FreeBuffers释放内存!");
#endif // _DEBUG
}
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(" FreeContexts释放内存出错!");
#endif // _DEBUG
break;
}
else
{
#ifdef _DEBUG
OutputDebugString(" FreeContexts释放内存!\r\n");
#endif // _DEBUG
}
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_SOCKE
大宝版本IOCP封装类



【大宝版本IOCP封装类】是一个针对网络编程中的异步I/O模型——完成端口(IO Completion Port, IOCP)进行封装的类库。IOCP是Windows操作系统提供的一种高效、可扩展的I/O机制,尤其适用于高并发的服务器场景。大宝版本的IOCP封装类,可能是某位开发者(昵称“大宝”)为了简化IOCP的使用而编写的,旨在帮助其他开发者更便捷地构建高性能的网络服务。 IOCP的基本原理是将I/O操作与处理结果的回调函数分离,当I/O操作完成后,系统会将结果放入完成端口,由工作线程从完成端口取出并执行相应的回调函数。这种方式可以避免传统的同步I/O模型中的阻塞问题,提高了系统的并行处理能力。 在大宝的代码中,我们可能看到以下几个关键知识点: 1. **IOCP对象创建**:需要通过`CreateIoCompletionPort`函数创建一个IOCP句柄,用于接收I/O操作的完成通知。 2. **工作线程池**:IOCP模型通常需要一组工作线程来处理完成的I/O请求。大宝的封装可能会包含创建和管理这些工作线程的逻辑。 3. **异步I/O操作**:使用`WSAAsyncSelect`或`WSARecvFrom`等API发起异步网络读写操作,并指定IOCP作为完成通知的接收者。 4. **GetQueuedCompletionStatus**:当有I/O操作完成时,通过调用`GetQueuedCompletionStatus`函数从IOCP中获取完成状态,包括完成状态码、传输的数据量以及关联的用户上下文信息。 5. **PostQueuedCompletionStatus**:在完成某个I/O操作后,通过`PostQueuedCompletionStatus`向IOCP提交完成状态,触发回调函数的执行。 6. **错误处理**:在IOCP的整个生命周期中,正确处理各种错误和异常情况是非常重要的,例如处理网络中断、资源不足等问题。 7. **性能优化**:大宝的封装可能还考虑了性能优化,如适当的线程池大小调整、I/O请求的批处理、减少锁的使用等。 8. **内存管理**:在处理大量并发连接时,内存管理也是关键。大宝的代码可能会包含内存池或其他内存管理策略,以降低内存分配和释放的开销。 9. **线程同步**:为了确保数据的一致性和完整性,大宝可能使用了互斥量、事件对象或信号量等同步机制。 10. **异常安全**:在IOCP的实现中,确保异常安全是必要的,防止在异常发生时资源泄露或状态损坏。 由于没有具体的源代码可供参考,以上分析基于对IOCP常见设计模式的理解。实际的大宝版本IOCP封装类可能包含更多的细节和特性,具体实现方式需要查看源代码才能深入了解。如果要深入学习和使用这个类库,建议配合相关文档和示例代码进行实践。

































- 1

- 粉丝: 17
- 资源: 111
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- FactoryIO与SCL语言结合的工业自动化流水线仿真入门教程
- 表贴式永磁同步电机非线性磁链观测器无感控制技术及其应用
- C#与Halcon结合的动态加载DLL工业自动化控制框架设计与实现
- 基于Carsim与Matlab/Simulink的五次多项式弯道换道联合仿真及控制优化
- 多目标点送餐机器人路径规划算法优化:融合A*与模拟退火的AGV室内仿真
- MATLAB/Simulink中永磁同步电机FOC与DTC控制策略的动静态性能对比分析
- 页岩气开采中二氧化碳驱替甲烷的COMSOL多物理场仿真及优化
- 逆变器I2300G1硬件设计详解:PCB布局、BOM选型与调试技巧
- 基于Crowbar电路的DFIG低电压穿越(LVRT)仿真模型及其应用
- 基于MATLAB的NSGA-Ⅱ多目标遗传算法:优势解析与性能优化
- YOLOv8热力图可视化:探索每层网络特征与模型内部视角
- 基于javaweb的学生成绩管理系统 .zip
- 基于JavaWeb的在线商城的设计与实现(java+jsp+servlet+Mysql+jquery+mybatis).zip
- 基于javaweb(jsp)-课程设计-图书购物网站.zip
- 基于javaweb+MVC模式的一个简单购物车实例.zip
- 基于javaweb的日程管理系统.zip



- 1
- 2
- 3
- 4
前往页