/*********************************************
类名 : CTcpIocpClient
功能 : TCP 客户端完成端口封装
QQ : 51171107
**********************************************/
#ifndef H_CTCP_IOCP_CLIENT_H
#define H_CTCP_IOCP_CLIENT_H
#include "CIocpHeader.h"
#include "CMemPool.h"
#include "CRecvThreadPool.h"
// 字符串的地址类型
class CTcpIocpClient
{
public:
CTcpIocpClient(void);
~CTcpIocpClient(void);
public:
// 开始
BOOL Start(IOHandleData* apHandleData);
// 结束
void Stop(void);
// 连接到指定IP地址
CTCPContext* IPConnect(const char* apSvrAddr, unsigned short asSvrPort);
// 连接到指定host地址
CTCPContext* HostConnect(const char* apHost, unsigned short asSvrPort);
// 发送数据
BOOL SendTo(Socket ahSocket, const char *apszBuff, int aiLen);
// 结束指定的会话
BOOL StopSession(CTCPContext* apSession);
private:
BOOL LocalStopSession(CTCPContext* apSession);
// 归还TCPContext
BOOL GiveBackCTCPContext(CTCPContext* apCTCPContext);
// 判断是IP地址还是域名
int IsIpOrHost(const char *apStrAddr);
// 初始化完成端口
BOOL InitCompletePort(SInt8 ai8WorkThreadCnt = 0);
// 关闭完成端口
void CloseCompletionPort(void);
// 工作线程入口
static ULong WorkThread(void* apObj);
// 工作线程切换
void WorkThread(void);
// 处理 e_IoRead状态
BOOL OnRead(ULong aulDataLen, SOverLappedEx* aOverlapex);
// 清除TCP连接
BOOL RemoveTcpConnect(CTCPContext* apTcpSocket);
// 释放OverLapped
BOOL GiveBackSOverLappedEx(SOverLappedEx* apOverlapped);
// 处理接受到得数据
BOOL HandleRecvData(CTCPContext* lpTcpSocket, char* apBuf,ULong aulLen);
// 处理线程池接收到得数据
static
void HandlePoolRecvData(Byte* lpData);
// 申请OverLapped
SOverLappedEx* AllocSOverLappedEx(EIOOperation aeType);
public:
// 工作状态
BOOL m_bWorkingState;
// 工作线程记数
SLong m_slWorkThreadCnt;
// 工作线程记数锁
CThreadLock m_oThreadCntLock;
// 已连接队列CONNECT添加
stdext::hash_set<CTCPContext*> m_oConnected;
// 已连接队列锁
CThreadLock m_oConnectedLock;
// 完成端口
HANDLE m_hCompLetePort;
// 连接队列缓冲池
CushionQueue<CTCPContext> m_oConnectedCache;
// 接收OverLap缓冲队列
CushionQueue<SOverLappedEx> m_oRecvOverlapCache;
// 处理IO数据
static IOHandleData* m_poRecv;
//Write overlap
WSAOVERLAPPED m_oWriteOverlap;
CThreadLock m_oWriteCriSection;
// 内存池
static CMemPool* m_oMemPool;
// TCP原始数据包大小
SInt16 m_OrgnlPackSize;
};
#endif//H_CTCP_IOCP_CLIENT_H
#include "StdAfx.h"
#include "CTcpIocpClient.h"
#include "CRunningLog.h"
#include "CPubfuncs.h"
#include "CIocpHeader.h"
IOHandleData* CTcpIocpClient::m_poRecv = 0;
CMemPool* CTcpIocpClient::m_oMemPool = 0;
/*******************************************
构造函数
*******************************************/
CTcpIocpClient::CTcpIocpClient(void) : m_hCompLetePort(INVALID_HANDLE_VALUE)
, m_slWorkThreadCnt(0)
, m_bWorkingState(FALSE)
, m_OrgnlPackSize(sizeof(CTCPOrgnlPack))
{
//m_oRecvThreadPool.InitPool(HandlePoolRecvData);
CTcpIocpClient::m_oMemPool = CMemPool::GetPool();
}
/*******************************************
析构函数
*******************************************/
CTcpIocpClient::~CTcpIocpClient(void)
{
}
/*******************************************
结束
*******************************************/
void CTcpIocpClient::Stop(void)
{
m_bWorkingState = FALSE;
Sleep(1000);
// 关闭完成端口
CloseCompletionPort();
SOverLappedEx* lpObj = NULL;
while (NULL != (lpObj = m_oRecvOverlapCache.GetNextObj()))
{
lpObj->m_oWsaBuffer.buf = NULL;
delete lpObj;
lpObj = NULL;
}
CTCPContext* lpContext = NULL;
while (NULL != (lpContext = m_oConnectedCache.GetNextObj()))
{
if (lpContext->m_oSocket != INVALID_SOCKET)
{
NOTICE_LOG("NOTICE: CTcpIocpClient::Stop 出现异常 context");
continue;
}
delete lpContext;
lpContext = NULL;
}
WSACloseEvent(m_oWriteOverlap.hEvent);
m_oWrite