winsock 完成端口 服务器模型(1)

//IOCPServer.h

#include <winsock2.h>
#include <windows.h>
#include <Mswsock.h>

#define BUFFER_SIZE 1024
#define MAXFREEBUFFERS 200
#define MAXFREECONTEXTS 100
#define MAXCONNECTIONS 2000
#define OP_ACCEPT 1
#define OP_RECV 2
#define OP_SEND 3

#pragma comment(lib,"WS2_32.lib")

//缓冲区对象
struct IOCPBUFFER
{
 WSAOVERLAPPED ol; //重叠I/O
 SOCKET sClient;   //新收到的客户端 (只对Listen套接字有效)
 char *buf;        //缓冲区指针
 int nLen;         //buf的长度
 ULONG nSequenceNumber;  //当前对象的序列号
 int nOperationType;     //操作类型 :OP_ACCEPT,OP_RECV ,OP_SEND
 IOCPBUFFER *pNext;     //指向下一个IOCPBUFFER
};

//客户上下文对象
struct IOCPCONTEXT
{
 SOCKET s; //套接字句柄
 sockaddr_in addrLocal; //连接的本地地址
 sockaddr_in addrRemote;//连接的远程地址
 int nOutstandingRecv; //此套接字上被抛出的重叠操作数量(recv)
 int nOutstandingSend; //此套接字上被抛出的重叠操作数量 (send)
 ULONG nReadSequence; //安排给接收下一个序列号
    ULONG nCurrentSequence;//当前要读的序列号
 CRITICAL_SECTION lock; //保护这个结构锁
 IOCPBUFFER *pOutofOrederReads; //记录没有按顺序完成的读I/O
 IOCPCONTEXT *pNext;  //指向下一个IOCPCONTEXT
};

class IOCPServer
{
public:
 IOCPServer(void);
 virtual ~IOCPServer(void);
 void Start(); //服务起动
 bool GetIsServerStart();  //获取程序是否运行
 char *GetErrorMsg();      //获取错误信息

public:
 void virtual CompletedRecvDate(IOCPBUFFER* pBuffer,IOCPCONTEXT* pContext);  //接收数据完成
 void virtual CompletedWriteDate(IOCPBUFFER* pBuffer,IOCPCONTEXT* pContext);//写完成
 void virtual ConnectionComplete(IOCPCONTEXT *pContext); //pContext客户已连接上
 void virtual DisConnection(IOCPCONTEXT *pContext);      //pContext客户断开连接
 BOOL WriteDate(char *buf,int len,IOCPCONTEXT *pContext);//写数据
 void ShutDown();

protected:
 void InitSocket();  //初始化
 void ResetValue(); 
 IOCPBUFFER* AllocBuffer(int nLen);   //从内存池中取一块可用的缓冲块,如果内存池中没有就从内存中分配空间
 void FreeBuffer(IOCPBUFFER* pBuffer);    //释放缓冲对象
 IOCPCONTEXT* AllocContext(SOCKET s); //从客户上下文列表中取一个客户上下文,如果列表为空就分配一个
 void FreeContext(IOCPCONTEXT* pContext);//释放客户上下文对象
 bool PostAccept(IOCPBUFFER* pBuffer);  //投递Accept
 bool PostRecv(IOCPBUFFER* pBuffer,IOCPCONTEXT* pContext); //投递Recv
 bool PostSend(IOCPBUFFER* pBuffer,IOCPCONTEXT* pContext); //投递write
 IOCPBUFFER* GetNextReadBuffer(IOCPCONTEXT* pContext,IOCPBUFFER* pBuffer); //按顺序读取缓冲区中的数据,包重组
 bool AddConnection(IOCPCONTEXT* pContext);  //添加已连接列表
 void CloseConnection(IOCPCONTEXT* pContext);//关闭连接
 void InsertToPostAccept(IOCPBUFFER *pBuffer);
 void RemoveFormPostAccept(IOCPBUFFER *pBuffer);
 void CloseAllConnects();  //关闭所有的连接
 void FreeBuffers();  //释放内存池
 void FreeContexts(); //释放空闲客户上下文列表

private:
 bool m_bIsServerStart;          //服务是否正常起动
 char *m_pErrorMsg;               //程序没有出错的原因

 BOOL m_bShutDown;//关闭服务

 IOCPBUFFER* m_pFreeBufferList;  //指向内存池列表的头指针
 CRITICAL_SECTION m_FreeBufferListLock; //保护内池列表锁
 int m_FreeBufferCount;               //内存池中缓冲区块的数量

 IOCPCONTEXT* m_pFreeContextList;     //空闲客户上下文列表指针
 CRITICAL_SECTION m_FreeContextListLock; //空闲客户上下文列表锁
 int m_FreeContextCount;              //空闲客户上下文的数量

 IOCPCONTEXT* m_pConnectContextList;  //被连接上的客户列表
 CRITICAL_SECTION m_ConnectContextListLock; //被连接上的客户列表锁
 int m_ConnectContextCount;//已连接的数量

 LPFN_ACCEPTEX m_lpfnAcceptEx;       //指向AcceptEx的指针
 LPFN_GETACCEPTEXSOCKADDRS m_lpfnGetAddr;  //指向日GetAcceptSockAddrs指针
 SOCKET m_sListen;  //监听套接字

 IOCPBUFFER * m_pPostAcceptList;  //被投出的accept
 CRITICAL_SECTION m_PostAcceptListLock;

 HANDLE m_hCompletion;  //完成端口句柄

 HANDLE m_hListenThread;  //监听线程名柄

 HANDLE m_hAcceptEvent;   //Accept事件
 HANDLE m_hRePostAcceptEvent; //重投Accept事件;

 HANDLE m_hWorkThread[2];
private:
 //线程函数
 static DWORD WINAPI _ListenThreadProc(LPVOID lpParam);
 static DWORD WINAPI _WorkerThreadProc(LPVOID lpParam);
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值