iocp 完成端口封装类 内存优化 高并发 接口简单

文章转自王牌软件---- 

class Iocp //完成端口 功能类
class IocpMemoryManager //此类提供IOCP 内存的管理

//Iocp.h
#pragma once
 
#include "IocpMemoryManager.h"
#include <windows.h>
 
 
#define MAXWORKERTHREADS 2
 
//iocp类封装
classCIocp
{
public:
    CIocp(void);
    ~CIocp(void);
 
    boolStartServer(intnPort = 4568, intnMaxConnections = 2000);//开始服务   监听端口,最大的连接数
    boolReStartServer();                                          //重启服务
    boolStopServer();                                             //停止服务
    intGetCurrentConnection();                                    //得到当前的连接数
    boolSendText(CIOCPContext *pContext, char*pszText, intnLen);//发送数据给客户端
    char* GetCustomLastError();                                    //获取最后的错误信息
 
protected:
    // 事件通知函数
    virtualvoid OnConnectionEstablished(CIOCPContext *pContext, CIOCPBuffer *pBuffer) = 0;      // 建立了一个新的连接
    virtualvoid OnConnectionClosing(CIOCPContext *pContext, CIOCPBuffer *pBuffer) = 0;          // 一个连接关闭
    virtualvoid OnConnectionError(CIOCPContext *pContext, CIOCPBuffer *pBuffer, intnError) = 0;// 在一个连接上发生了错误
    virtualvoid OnReadCompleted(CIOCPContext *pContext, CIOCPBuffer *pBuffer) = 0;              // 一个连接上的读操作完成
    virtualvoid OnWriteCompleted(CIOCPContext *pContext, CIOCPBuffer *pBuffer) = 0;             // 一个连接上的写操作完成
 
private:
    IocpMemoryManager* m_pIocpMemoryManager;//此类提供IOCP 内存的管理
 
    boolm_bServerStarted;      //服务是否已经启动
    intm_nPort;                // 服务器监听的端口
    intm_nInitialAccepts;      //初始化投递的接受请求数
    intm_nInitialReads;        //初始化投递Accept数
    intm_nMaxAccepts;          //最大接受数
    intm_nMaxSends;            //单套接字最大发送数
    intm_nMaxListenCount;      //最大的监听数
    intm_nMaxWorkerThreads;    //最大工作线程数
    char* m_pcaErrorMessage;    //错误信息 取得最后一个错误信息
    //Event
    HANDLEm_hAcceptEvent;      // 用于投递Accept请求
    HANDLEm_hRepostEvent;
    LONGm_nRepostCount;
 
    //套接字信息
    HANDLEm_hListenThread;         // 监听线程
    HANDLEm_hCompletion;           // 完成端口句柄
    SOCKET m_sListen;               // 监听套节字句柄
    LPFN_ACCEPTEX m_lpfnAcceptEx;   // AcceptEx函数地址
    LPFN_GETACCEPTEXSOCKADDRS m_lpfnGetAcceptExSockaddrs; // GetAcceptExSockaddrs函数地址
 
private:
    boolDoWSAStartup();                  //初始化 socket库
    voidInitData();                      //初始化数据
    voidInitEvent();                     //初始化Event
    boolCreateIocpPort();                //创建完成端口
    voidSetCustomLastError(char* error); //设置错误
 
    boolPostAccept(CIOCPBuffer *pBuffer);                       // 投递接受I/O
    boolPostSend(CIOCPContext *pContext, CIOCPBuffer *pBuffer); // 投递发送I/O
    boolPostRecv(CIOCPContext *pContext, CIOCPBuffer *pBuffer); // 投递接收I/O
 
    voidHandleIO(DWORDdwKey, CIOCPBuffer *pBuffer, DWORDdwTrans, intnError);  //总请求处理
    voidHandleAccept(CIOCPBuffer *pBuffer, DWORDdwTrans);                       //处理接收请求
    voidHandleRead(CIOCPContext *pContext, CIOCPBuffer *pBuffer, DWORDdwTrans); //处理读请求
    voidHandleWrite(CIOCPContext *pContext, CIOCPBuffer *pBuffer, DWORDdwTrans);//处理写请求
 
    staticDWORD WINAPI _ListenThreadProc(LPVOIDlpParam);    //监听线程
    staticDWORD WINAPI _WorkerThreadProc(LPVOIDlpParam);    //工作线程
};
 

//IocpMemoryManager.h
 
#pragma once
#include <winsock2.h>
#include <Mswsock.h>
#include <list>
#include <iostream>
usingnamespace std;
//此类提供IOCP 内存的管理
#define BUFFER_SIZE 1024*4      // I/O请求的缓冲区大小  单次发送最大 4096
// 这是per-I/O数据。它包含了在套节字上处理I/O操作的必要信息
classCIOCPBuffer
{
public:
    CIOCPBuffer();
    ~CIOCPBuffer();
    boolisUsed;
    WSAOVERLAPPED ol;
    SOCKET sClient;         // AcceptEx接收的客户方套节字
    char*buff;             // I/O操作使用的缓冲区
    intnLen;               // buff缓冲区(使用的)大小
    ULONGnSequenceNumber;  // 此I/O的序列号
    intnOperation;         // 操作类型
#define OP_ACCEPT   1
#define OP_WRITE    2
#define OP_READ     3
};
 
// 这是per-Handle数据。它包含了一个套节字的信息
classCIOCPContext
{
public:
    CIOCPContext();
    ~CIOCPContext();
    boolisUsed;
    SOCKET s;                       // 套节字句柄
    SOCKADDR_IN addrLocal;          // 连接的本地地址
    SOCKADDR_IN addrRemote;         // 连接的远程地址
    boolbClosing;                  // 套节字是否关闭
    intnOutstandingRecv;           // 此套节字上抛出的重叠操作的数量
    intnOutstandingSend;
    ULONGnReadSequence;            // 安排给接收的下一个序列号
    ULONGnCurrentReadSequence;     // 当前要读的序列号
    list<CIOCPBuffer*> pOutOfOrderReadsList;  // 记录没有按顺序完成的读I/O
    CRITICAL_SECTION Lock;          // 保护这个结构
};
 
classIocpMemoryManager
{
public:
    IocpMemoryManager(void);
    ~IocpMemoryManager(void);
 
    staticIocpMemoryManager* GetInstence();
 
    intm_nMaxFreeBuffers;      //最大的空闲Buffer
    intm_nMaxFreeContexts;     //最大的空闲Contexts
    intm_nMaxConnections;      //最大的连接数
 
    intGetContextListCount(){returnm_contextList.size();}
     
    //Accept 操作
    boolInsertAPendingAccept(CIOCPBuffer *pBuffer);
    boolRemoveAPendingAccept(CIOCPBuffer *pBuffer);
    intGetPendingAcceptCount();
 
    //buffer 操作 
    CIOCPBuffer* AllocateBuffer(intnLen = BUFFER_SIZE);//buffer 申请
    voidReleaseABuffer(CIOCPBuffer *pBuffer);          //buffer 释放 
    CIOCPBuffer* GetANoUseBuffer();                     //获取一个空闲的buffer
    intGetFreeBuffersCount();                          //获取空闲的Buffer的数目
 
    //Contexts 操作
    CIOCPContext* AllocateContext(constSOCKET& sClient);   //Contexts 申请
    voidReleaseAContext(CIOCPContext *pBuffer);            //Contexts 释放 
    CIOCPContext* GetANoUseContexts();                      //获取一个空闲的Contexts
    intGetFreeContextsCount();                             获取空闲的Contexts的数目
 
    voidCloseAConnection(CIOCPContext *pContext);
    voidCloseAllConnections();                             //关闭所有的socket 但不FreeContexts();
 
    voidFreeBuffers();     //清空所有Buffers
    voidFreeContexts();    //清空所有Contexts
 
    // 取得下一个要读取的
    CIOCPBuffer *GetNextReadBuffer(CIOCPContext *pContext, CIOCPBuffer *pBuffer);
 
    //获取工作线程最大数 = CPU个数*2{最佳}
    intGetMaxWorkerThreadCount();
 
    voidHandlePendingAcceptTimeOut();
 
private:
    list<CIOCPBuffer*> m_bufferList; //统一管理 【管理所有申请的buffer】
    list<CIOCPContext*> m_contextList;//统一管理 【管理所有申请的context】
    list<CIOCPBuffer*> m_pPendingAcceptsList;
 
    CRITICAL_SECTION m_FreeBufferListLock;
    CRITICAL_SECTION m_FreeContextListLock;
    CRITICAL_SECTION m_PendingAcceptsLock;
    CRITICAL_SECTION m_ConnectionListLock;
};


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值