您的位置:首页 > 其它

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

2007-12-11 08:46 344 查看
//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);
};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: