基于C++的纯面向对象的通用高性能大并发TCP-SERVER/CLIENT开发框架实践系列之基础篇
yijian 2008-12-21 technologier@126.com
1. 前言
本篇主要介绍Servant和Client都会使用到的公共基础,主要包括两大部分:一是对线程相关的封装;另是对Socket相关的封装。这些基础类间的关系比较简单,但是和Server/Client框架息息相关。
2. 线程相关
2.1. 类图
2.2. CShared
2.2.1. 功能
CShared实现了引用计数器,引用计数采用原子锁。所有需要使用到引用计数的类都可以从它派生出来。
2.2.2. 定义
Class CShared
{
public:
CShared(); // 初始化m_refcount为0
int IncRef(); // 对m_refcount增一
int DecRef(); // 对m_refcount减一
int GetRef(); // 返回m_refcount的值
private:
int m_refcount; // 引用计数器变量
};
2.3. CThread
2.3.1. 功能
将线程封装成一个类,所要创建一个线程时,只需要从它继承,并实现Run方法即可。
2.3.2. 定义
class CThread: public CShared
{
private:
virtual void run() = 0; // 线程执行体,子类必须实现这个方法
public:
virtual bool BeforeRun() { return true; } // 线程启动之前,可用来做一些初始化
virtual void AfterRun(int errcode) { } // 线程启动之后,如果errcode为0表示启动成功,否则表示一个出错代码,可使用strerror(errcode)得到具体的出错信息
public:
bool start(); // 启动线程
void stop() { m_stop = true; } // 非强制性地停止线程
protected:
bool IsStop() const { return m_stop; } // 判断是否要退出线程
Private:
pthread_t m_thread // 线程句柄
bool m_stop; // 是否停止标识
};
2.4. CThreadPool
2.4.1. 功能
提供一个通用的线程池功能。
2.4.2. 定义
template <class CThreadClass>
class CThreadPool
{
public:
typedef std::list<CThreadClass*> TThreadList;
public:
bool create(uint32_t size); // 创建和启动线程,线程个数由size指定
void destroy(); // 停止和销毁所有线程
private:
TThreadList m_lstThread;
};
2.5. CMutex
2.5.1. 功能
不可递归的锁。
2.5.2. 定义
class CMutex
{
protected:
CMutex(bool rec):m_rec(rec) {}
public:
CMutex():m_rec(false); // 初始化mutex
~CMutex(); // 释放mutex
bool lock(); // 加锁,出错代码由errno保存
bool unlock(); // 解锁,出错代码由errno保存
private:
bool m_rec; // 是否可递归标识,如果为true则可递归,否则不可以递归
pthread_mutex_t m_mtx; // mutex句柄
};
2.6. CRecMutex
2.6.1. 功能
可递归的锁。
2.6.2. 定义
class CRecMutex: public CMutex
{
public:
CRecMutex():CMutex(true) {}
};
2.7. CMutexGuard
2.7.1. 功能
智能锁,在构造中加锁,在析构中自动解锁。
2.7.2. 定义
template <class CMutexClass>
class CMutexGuard
{
friend class CCondition;
public
CMutexGuard(CMutexClass& mutex):m_mutex(mutex) { mutex.lock(); }
~CMutexGuard() { m_mutex.unlock(); }
private:
CMutexClass& m_mutex;
};
2.8. CCondition
2.8.1. 功能
Posix条件的封装。
2.8.2. 定义
class CCondition
{
public:
CCondition(); // 初始化m_cond
~CCondition(); // 释放m_cond
bool TimedWait(uint32_t milliSeconds); // 以毫秒方式等待,直到超时
bool signal(); // 唤醒等待者
private:
pthread_cond_t m_cond; // 条件句柄
};
2.9. CArrayQueue
2.9.1. 功能
以数组方式实现的队列。
2.9.2. 应用场景
用于连接池,以避免每来一个连接创建一个连接对象。
2.9.3. 定义
template <type TNodeType>
class CArrayQueue
{
public:
CArrayQueue(uint32_t size);
~CArrayQueue();
bool push(TNodeType pNode); // 入栈操作
TNodeType pop(); // 出栈操作
bool empty() const; // 如果队列为空,则返回true,否则返回false;
bool full() const; // 如果队列满,则返回true,否则返回false;
private:
int m_front; // 队首下标
int m_rear; // 队尾下标
TNodeType* m_pQueueArray; // 队列用的数组
};
2.10. CListQueueNode
2.10.1. 功能
链表队列结点类型,实现基本的双向链表操作。
2.10.2. 定义
class CListQueueNode
{
public:
CListQueueNode();
CListQueueNode* GetNext() const;
void SetNext(CListQueueNode* pNext);
CListQueueNode* GetPrev() const;
void SetPrev(CListQueueNode* pPrev);
private:
CListQueueNode* m_next;
CListQueueNode* m_prev;
};
2.11. CListQueue
2.11.1. 功能
链表队列,提供push到队尾和从队首遍历的功能,并提供链表的随机删除任意结点功能。
2.11.2. 应用场景
超时连接的管理,连接按超时时间长短存储队列中,并可从链表中随机删除其中任何一个结点。
2.11.3. 定义
class CListQueue
{
public:
CListQueue();
CListQueueNode* front() const; // 返回队首指针
void push(CListQueueNode* pNode); // 将结点添加到队尾
void remove(CListQueueNode* pNode); // 从链表中删除pNode这个结点
private:
CListQueueNode* m_pFront; // 队首指针
CListQueueNode* m_pRear; // 队尾指针
};
3. Socket相关
3.1. 类图
3.2. CHandle
3.2.1. 功能
所有句柄类对象的基类,包括socket和管道。
3.2.2. 定义
class CHandle
{
public:
CHandle();
SetHandle(int fd); // 设置句柄
int GetHandle() const; // 返回句柄值
THandleType GetType() const; // 得到句柄对象类型
bool SetNonBlock(bool block); // 阻塞和非阻塞属性设置
uint32_t GetEpollEvents() const; // 返回已注册的EPOLL事件
void SetEpollEvents(uint32_t events); // 设置已注册的EPOLL事件
private:
int m_fd; // 句柄
uint32_t m_events; // Epoll事件
THandleType m_type; // 句柄类型,请参见THandleType一节
};
3.3. THandleType
3.3.1. 功能
句柄对象的类型。
3.3.2. 定义
typedef enum
{
htPipe, // 管道
htTcpListener, // 监听者
htTcpServant, // 服务端的侍者
htTcpClient // 客户端
}THandleType;
3.4. CEpoller
3.4.1. 功能
对epoll的封装。
3.4.2. 定义
class CEpoller
{
public:
bool create(uint32_t size); // 创建一个epoll,其中size是epoll大小
void destroy(); // 销毁epoll
bool AddEvents(CHandle* pHandle, uint32_t events); // 添加一个CHandle
bool ModEvents(CHandle* pHandle, uint32_t events); // 修改一个CHandle
bool DelEvents(CHandle* pHandle); // 删除一个CHandle
int TimedWait(uint32_t milliSeconds); // 毫秒级超时等待
CHandle* GetHandle(int index) const; // TimedWait成功返回后,通过这个方法得到是哪个CHandle
};
3.5. CSocket
3.5.1. 功能
对TCP和UDP通用部分的封装。
3.5.2. 定义
class CSocket
{
public:
CSocket();
bool create(bool tcp); // 创建一个SOCKET,如果tcp为true,则创建TCP套接字,否则创建UDP套接字
bool IsSSL() const; // 如果返回true,则表示支持SSL,否则不支持
void SetSSL(bool ssl); // 更新是否支持SSL标识
private:
bool m_ssl; // 否支持SSL标识
};
3.6. CTcpListener
3.6.1. 功能
TCP监听套接字的封装,提供listen和accept两个方法。
3.6.2. 定义
class CTcpListener: public CSocket
{
public:
bool listen(const char* ip, uint16_t port); // 监听
int accept(); // 接受一个连接,并返回连接的句柄
};
3.7. TListenParam
3.7.1. 功能
监听参数结构体。
3.7.2. 定义
typedef struct
{
bool ssl; // 是否作为一个SSL类型的监听者
uint16_t port; // 监听端口
std::string ip; // 监听IP地址
}TListenParam;
3.8. TListenParamList
3.8.1. 功能
监听参数结构体链表。
3.8.2. 定义
typedef std::list<TListenParam*> TListenParamList;
3.9. CTcpListenerManager
3.9.1. 功能
CTcpListener管理类,用来批量的监听。
3.9.2. 定义
template <class CListenerClass>
class CTcpListnerManager
{
public:
void add(TListenParam&); // 添加一个监听
bool create(); // 创建所有监听
void destroy(); // 销毁所有监听
private:
TListenParamList m_lstListenParam; // 监听参数表
};
3.10. CTcpConnector
3.10.1. 功能
TCP服务端和客户端通讯连接的封装。
3.10.2. 定义
class CTcpConnector: public CSocket
{
public:
int receive(const char* buf, uint32_t buflen); // 接收数据
int send(char* buf, uint32_t buflen); // 发送数据
};
3.11. CServant
3.11.1. 功能
TCP服务端用来通讯的连接,由于服务端是被动的,有侍者的含义。
3.11.2. 定义
class CServant
{
public:
void attach(int fd); // 将CServant关联到一个fd上。
};
3.12. CServantPool
3.12.1. 功能
CServant池,主要功能是避免来一个请求需要创建和销毁一个CServant对象。
3.12.2. 定义
class CServantPool
{
public:
bool create(uint32_t size); // 创建Servant池,size为池中Servant个数
void destroy(); // 释放所有Servant
CServant* borrow(); // 从池中借出一个Servant
void reclaim(CServant* pServant); // 将一个Servant还回到池中
private:
CArrayQueue<CServant*> m_ServantQueue;
};
3.13. CTcpClient
3.13.1. 功能
TCP客户端连接对象。
3.13.2. 定义
class CTcpClient: public CSocket
{
public:
bool TimedWait(uint32_t MilliSeconds,const char* ServIP, uint16_t ServPort, const char* LocalIP=NULL,uint16_t LocalPort=0); // 带超时功能的连接,支持绑定本地IP和端口
};
3.14. TConnectParam
3.14.1. 功能
客户端需要指定的连接参数。
3.14.2. 定义
typedef struct
{
bool ssl; // 是否为SSL连接
uint16_t server_port; // 服务端的监听端口
uint16_t local_port; // 需要绑定的本地端口
std::string server_ip; // 服务端监听的IP
std::string local_ip; // 需要绑定的本地IP
}TConnectParam;
3.15. CTcpClientManager
3.15.1. 功能
CTcpClient管理类,以支持批量连接到多个服务端。
3.15.2. 定义
class CTcpClientManager
{
public:
void add(const TConnectParam&); // 添加一个连接
bool create(); // 执行所有连接
void destroy(); // 断开所有连接,并销毁所有CTcpClient
};
3.16. CSSLmanager
3.16.1. 功能
SSL管理类,提供SSL库初始化等功能。
3.16.2. 定义
class CSSLmanager
{
public:
bool SSLinit();
void SSLfini();
};
3.17. CTimeoutable
3.17.1. 功能
可超时对象接口,提供时间戳功能。
3.17.2. 定义
class CTimeoutable
{
public:
time_t GetTimestamp() const; // 返回时间戳
void UpdateTimestamp(time_t timestamp); // 更新时间戳
private:
time_t m_timestamp; // 时间戳
};
3.18. ITimeoutEvent
3.18.1. 功能
超时回调接口,以便在超时时,框架使用者可以做一些处理,如关闭连接等。
3.18.2. 定义
class ITimeoutEvent
{
public:
virtual void OnTimeout(CTimeoutable*) = 0;
};
3.19. CTimeoutManager
3.19.1. 功能
超时管理类。CTimeoutManager借助CListQueue来管理超时连接。
3.19.2. 定义
class CTimeoutManager
{
public:
void CheckTimeout(); // 检测超时的连接,如果超时,则将超时的从超时队列中删除,并回调ITimeoutEvent方法,以便将超时的连接关闭掉
void add(CTimeoutable*); // 添加一个连接到超时队列中
void remove(CTimeoutable*); // 从超时队列中删除一个连接
};