ChatServer
一个TCP服务器必然会有连接的接收,维持,收发数据等逻辑。那我们就要基于asio完成这个服务的搭建。主服务是这个样子的
1 |
|
CServer类的声明
1 |
|
构造函数中监听对方连接
1 | CServer::CServer(boost::asio::io_context& io_context, short port):_io_context(io_context), _port(port), |
接受连接的函数
1 | void CServer::StartAccept() { |
AsioIOServicePool
从AsioIOServicePool中返回一个可用的iocontext构造Session,然后将接受的新链接的socket写入这个Session保管。
AsioIOServicePool已经在前面讲解很多次了,它的声明如下
1 |
|
AsioIOServicePool具体实现
1 |
|
CServer的处理连接逻辑
1 | void CServer::HandleAccept(shared_ptr<CSession> new_session, const boost::system::error_code& error){ |
Session层
上面的逻辑接受新链接后执行Start函数,新链接接受数据,然后Server继续监听新的连接
1 | void CSession::Start(){ |
先读取头部数据
1 | void CSession::AsyncReadHead(int total_len) |
上面的逻辑里调用asyncReadFull读取整个长度,然后解析收到的数据,前两个字节为id,之后两个字节为长度,最后n个长度字节为消息内容。
1 | //读取完整长度 |
读取指定长度
1 | //读取指定字节数 |
读取头部成功后,其回调函数内部调用了读包体的逻辑
1 | void CSession::AsyncReadBody(int total_len) |
读取包体完成后,在回调中继续读包头。以此循环往复直到读完所有数据。如果对方不发送数据,则回调函数就不会触发。不影响程序执行其他工作,因为我们采用的是asio异步的读写操作。
当然我们解析完包体后会调用LogicSystem单例将解析好的消息封装为逻辑节点传递给逻辑层进行处理。
LogicSystem
我们在逻辑层处理
1 | void LogicSystem::RegisterCallBacks() { |
并在构造函数中注册这些处理流程
1 | LogicSystem::LogicSystem():_b_stop(false){ |
总结
到此,完成了ChatServer收到QT客户端发送过来的长链接请求,并解析读取的数据,将收到的数据通过tcp发送给对端。接下来还要做ChatServer到GateServer的token验证,判断是否合理,这个教给之后的文章处理。