系列文章目录
《ZLToolKit源码学习笔记》(1)VS2019源码编译
《ZLToolKit源码学习笔记》(2)工具模块之日志功能分析
《ZLToolKit源码学习笔记》(3)工具模块之终端命令解析
《ZLToolKit源码学习笔记》(4)工具模块之消息广播器
《ZLToolKit源码学习笔记》(6)线程模块之整体框架概述
《ZLToolKit源码学习笔记》(7)线程模块之线程池组件:任务队列与线程组
《ZLToolKit源码学习笔记》(8)线程模块之线程负载计算器
《ZLToolKit源码学习笔记》(9)线程模块之任务执行器
《ZLToolKit源码学习笔记》(11)线程模块之工作线程池WorkThreadPool
《ZLToolKit源码学习笔记》(12)事件轮询模块之整体框架概述
《ZLToolKit源码学习笔记》(13)事件轮询模块之管道的简单封装
《ZLToolKit源码学习笔记》(14)事件轮询模块之定时器
《ZLToolKit源码学习笔记》(15)事件轮询模块之事件轮询器EventPoller
《ZLToolKit源码学习笔记》(16)网络模块之整体框架概述
《ZLToolKit源码学习笔记》(17)网络模块之基础接口封装类SockUtil
《ZLToolKit源码学习笔记》(18)网络模块之Buffer缓存
《ZLToolKit源码学习笔记》(19)网络模块之套接字封装
《ZLToolKit源码学习笔记》(20)网络模块之TcpServer
《ZLToolKit源码学习笔记》(21)网络模块之TcpClient与Session(本文)
《ZLToolKit源码学习笔记》(22)网络模块之UdpServer
前言
本节学习ZLToolKit的TCP客户端封装以及服务器侧收到客户端连接后的Session封装。
目录
一、TcpClient
使用参见ZLToolKit\tests\test_tcpClient.cpp文件。
要访问到受保护的成员函数,必须继承TcpClient,因为TcpClient继承了std::enable_shared_from_this,且要实现多态,所以必须使用智能指针,如下:
class TestClient: public TcpClient {
public:
typedef std::shared_ptr<TestClient> Ptr;
TestClient():TcpClient() {
DebugL;
}
protected:
virtual void onConnect(const SockException &ex) override{
//连接结果事件
InfoL << (ex ? ex.what() : "success");
}
virtual void onRecv(const Buffer::Ptr &pBuf) override{
//接收数据事件
DebugL << pBuf->data() << " from port:" << get_peer_port();
}
virtual void onFlush() override{
//发送阻塞后,缓存清空事件
}
virtual void onErr(const SockException &ex) override{
//断开连接事件,一般是EOF
WarnL << ex.what();
}
virtual void onManager() override{
//定时发送数据到服务器
}
};
TestClient::Ptr client(new TestClient());//必须使用智能指针
client->startConnect("127.0.0.1",9000);//连接服务器
二、Session
每一个客户端连接在服务器侧都对应一个session。
一个server线程管理的所有session存储在_session_map中,对于TcpServer,每一个server线程都有独立的_session_map,而UdpServer是所有server线程共享同一个_session_map(udp是无连接的,防止同一客户端数据被匹配到不同的线程中去处理)。
SessionMap存储所有session, 系统当前所有会话,包括TCP和UDP的,看代码这个实际上并没有使用,仅在其友元类SessionHelper中操作了添加和删除。
SessionHelper类,将session、server、SessionMap关联起来;
class SessionHelper {
public:
using Ptr = std::shared_ptr<SessionHelper>;
SessionHelper(const std::weak_ptr<Server> &server, Session::Ptr session);
~SessionHelper();
const Session::Ptr &session() const;
private:
string _identifier;
Session::Ptr _session;
SessionMap::Ptr _session_map;
std::weak_ptr<Server> _server;
};
Session类继承自SocketHelper,可参见《ZLToolKit源码学习笔记》(19)网络模块之套接字封装_秦时小-优快云博客。
其派生类TcpSession与UdpSession未新增任何实现,仅继承了Session。
使用时,用户必须继承Session并且实现其纯虚函数,如下:
class EchoSession: public TcpSession {
public:
EchoSession(const Socket::Ptr &sock) :
TcpSession(sock) {
}
virtual void onRecv(const Buffer::Ptr &buf) override{
TraceL << buf->data() << " from port:" << get_local_port();
send(buf);
}
virtual void onError(const SockException &err) override{
//客户端断开连接或其他原因导致该对象脱离TCPServer管理
WarnL << err.what();
}
virtual void onManager() override{
//定时管理该对象,譬如会话超时检查
}
private:
Ticker _ticker;
};
TcpServer::Ptr server(new TcpServer());
server->start<EchoSession>(9000);//监听9000端口