我的IOCP学习笔记 - 相关类定义

类EasyIocp定义:

class EasyIocp 
{
public:
	EasyIocp();
	~EasyIocp();

public:
	static BOOL GetExtendSockFunc(SOCKET sock, LPVOID inBuff, DWORD inSize, LPVOID outBuff, DWORD outSize);
	static int WinSockStart();
	static int WinSockClean();

	///函数:投递一个recv请求。
	bool PostRecv(SOCKET transSock);
	///函数:投递一个send请求。
	bool PostSend(SOCKET transSock, char *data, int len);

	bool start(sockaddr_in *bindAddr = NULL);
	bool stop();

public:
	inline HANDLE GetComletionPort()
	{ return hCompPort_; }

	void RemoveClient(SOCKET sock);

private:
	void Construct();
	void Destruct();
	void InitThreadPool();
	void FreeThreadPool();
	void InitIocp();
	void FreeIocp();

	void InitListenSocket();
	///函数:投递一个accpet请求。
	void PostAccept(CompListenKey *listenKey, int index);
	///函数:一个accept请求返回,等待处理。
	void DoAccept(CompListenKey *listenKey, OVERLAPPED *ov, DWORD transBytes);
	void DoAcceptWithData(CompListenKey *listenKey, int index, EasyIocpBuffer *iocpBuffer, sockaddr_in *serverAddr, sockaddr_in *clientAddr);
	void DoAcceptWithoutData(CompListenKey *listenKey, int index, sockaddr_in *serverAddr, sockaddr_in *clientAddr);

	///函数:投递一个recv请求。
	bool PostRecv(CompTransmitKey *transKey, bool reset = true);
	///函数:有数据到达。
	void DoRecv(CompTransmitKey *transKey, DWORD transBytes);
	///函数:投递一个send请求。
	bool PostSend(CompTransmitKey *transKey);
	///函数:有数据已发送。
	void DoSend(CompTransmitKey *transKey, DWORD transBytes);

	///函数:仅仅作为调试时调用。
	void PushToDebug(CompTransmitKey *transKey);
private:
	///线程池
	TP_CALLBACK_ENVIRON tpCBE_;
	PTP_WORK *ptpWorks_;	//每个数组成员,标识一个回调函数
	EasyIocpStruct::WORK_ARG *workArgs_;		//回调函数参数
	int worksNum_;	//回调函数的数量
	///函数:工人函数。
	static void NTAPI TPCallBack(PTP_CALLBACK_INSTANCE Instance, PVOID pParam, PTP_WORK Work);
	///函数:处理具体的业务。
	static void DealCompletionPacket(EasyIocp *iocpModel, CompletionKey *compKey, LPOVERLAPPED pOv, DWORD transBytes);

	static void ClearShutFlag();
	static void SetShutFlag();
	static bool IsShutDown();
	static volatile long shutDownFlag_;		//关闭标识

	///IOCP
	HANDLE hCompPort_;
	sockaddr_in bindAddr_;
	CompListenKey compListen_;	//处理监听
	EasyClients easyClients_;	//处理连接的客户端

	LPFN_ACCEPTEX funcAcceptEx_;	//拓展函数
	LPFN_GETACCEPTEXSOCKADDRS funcGetAcceptExSockAddrs_;	//拓展函数
};


类CompletionKey定义,与套接字关联。

//
///类 CompletionKey ,虚基类作为socket与completion port关联时的key参数指针。
class CompletionKey
{
protected:
	CompletionKey(EasyIocpKeyType keyType)
		: keyType_(keyType)
	    , sock_(INVALID_SOCKET)
		, operType_(operInvalid)
	{}

public:
	virtual CompletionKey* clone() = 0;

	EasyIocpOper GetOperType() const
	{ return operType_; }

	void SetOperType(EasyIocpOper oper)
	{ operType_ = oper; }

	EasyIocpKeyType GetKeyType() const
	{ return keyType_; }

	SOCKET GetSocket() const
	{ return sock_; }

	void SetSocket(SOCKET sock)
	{ sock_ = sock; }

	void CloseSocket()
	{ if(sock_ != INVALID_SOCKET) closesocket(sock_); }

protected:
	SOCKET sock_;
	EasyIocpOper operType_;
	EasyIocpKeyType keyType_;
};


//
///类 CompListenKey ,作为listen socket与completion port关联时的key参数。
///由于工人线程函数有可能同时使用CompListenKey指针,注意多线程操作。
class CompListenKey : public CompletionKey
{
public:
	CompListenKey();

public:
	CompletionKey* clone();

	int GetIndex(OVERLAPPED *ovAddr);

	EasyIocpBuffer* GetOneBuffer(int index);
	OVERLAPPED* GetOneOverlapped(int index);
	SOCKET GetOneAcceptSock(int index);

	void ClearOne(int index);
	void Clear();

	BOOL SetOneAcceptSock(int index, SOCKET sock);

private:
	//下面数组的索引值由重叠结构标识
	OVERLAPPED ovs_[EASYIOCP_ACCEPT_NUM];		//重叠结构,每投递一个请求对应一个重叠结构
	SOCKET acceptSocks_[EASYIOCP_ACCEPT_NUM];
	EasyIocpBuffer iocpBuffers_[EASYIOCP_ACCEPT_NUM];
};


//
///类 TransmitKey, 实际的收发数据的socket与completion key关联时的key参数。
class CompTransmitKey : public CompletionKey
{
public:
	CompTransmitKey();

public:
	CompletionKey* clone();

	void SetServerAddr(sockaddr_in *addr);
	void SetClientAddr(sockaddr_in *addr);
	void GetBothAddr(sockaddr_in *server, sockaddr_in *client);

	EasyIocpBuffer* GetBuffer();

	OVERLAPPED* GetOverlapped();

private:
	OVERLAPPED ov_;
	EasyIocpBuffer iocpBuffer_;
	sockaddr_in serverAddr_;	//建立连接时服务端地址
	sockaddr_in clientAddr_;	//建立连接时客户端地址
};

类EasyIocpBuffer,记录传输的数据。

class EasyIocpBuffer
{
public:
	EasyIocpBuffer();
	///函数:赋值操作符,仅仅copy缓冲区数据。
	EasyIocpBuffer& operator=(const EasyIocpBuffer& iocpBuffer);

public:
	void Reset();

	///函数:有新的数据发送或者接收时,先调用AddTransBytes函数累加,然后调用IsTransComplete函数查看是否传输完毕。
	DWORD AddTransBytes(DWORD transBytes);
	///函数:数据接收是否完整。数据由 消息头+消息本身 两部分组成。消息头固定为 sizeof(LONG32)字节表示数据的字节数。
	bool IsTransComplete();

	///函数:返回已经传输的字节数。
	DWORD GetTransBytes();
	///函数:获取WSABuff。
	WSABUF* GetWSABuf();
	///函数:获取实际数据的字节数。
	DWORD GetBodySize();
	///函数:获取实际的消息,不包括消息头。
	DWORD GetBody(char *data, DWORD len);
	///函数:设置发送的数据。
	bool SetBody(char *data, DWORD len);
public:
	static const BYTE headerSize;		//消息头的大小,固定为 sizeof(ULONG32) 字节

private:
	DWORD transmitedBytes_;	//已经传送的字节数,包括消息头
	DWORD totalBytes_;		//消息本身的字节数,不包括消息头
	WSABUF wsaBuf_;
	char buffer_[EASYIOCP_MAX_BUFF];	//缓冲区,存放消息头+消息本身
};

代码有上传到CSDN,点击这里。但还是推荐到这里查看源码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值