boost用asio设计TCP服务器中单连接的设计
来源:互联网 发布:nba2010总决赛数据 编辑:程序博客网 时间:2024/06/05 12:01
在boost用asio设计TCP服务器的关键技术中,设计了tcp连接的管理类channel和处理io_service中多线程的工作方法,针对单个tcp连接的处理类session,核心的方法是接收和发送数据。
其中async_read_until与boost::asio::streambuf的组合,据说是可用处理粘包的问题,我打算下一个版本再用,这里用到的接收数据的buffer基于char来构造的。
重点是session类的设计,头文件如下
#pragma once #include <boost/asio.hpp> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp>#include <boost/enable_shared_from_this.hpp> #include "CircledBuffer.h"//::public boost::asio::ip::tcp::socketclass channel;class session;typedef boost::shared_ptr<session> session_ptr;class session: public boost::enable_shared_from_this<session> {public:session(boost::asio::io_service &io_service,channel& _channel);~session();bool started_;bool started() const;void start();void stop();void start_send(char* cmd);boost::asio::ip::tcp::socket &socket();std::string getRemoteAddr();int getRemotePort();int getSessionId(){return sessionId;};int heartbeat_count_;static long LastSessionId;private:boost::asio::ip::tcp::socket socket_;boost::asio::streambuf sbuf_;//TODO use circleBuffer instead of them.enum{max_msg=256};unsigned char write_buffer[max_msg];///////////////////////////////////CircledBuffer readBuffer;unsigned int readIndex;int sessionId;channel& p_channel;boost::asio::strand strand_;boost::asio::deadline_timer sessionAliveTimer;///////////////////////////not understand why to use this two.// std::size_t check_frame(const boost::system::error_code &ec, std::size_t bytes_transferred);//check data// void parse_frame(const boost::system::error_code &ec, std::size_t bytes_transferred);//parse data.void receive_handler(const boost::system::error_code &ec, std::size_t bytes_transferred);void send_handler(const boost::system::error_code &ec);void processCmd(std::size_t bytes_transferred);void _processCmd(std::size_t bytes_transferred);void _start();void _stop();void _start_send(char* cmd);void _setTimer(int sec);void _checkHeartBeat(const boost::system::error_code& /*e*/, boost::asio::deadline_timer* t);private:session(const session& other);const session operator=( const session& rhs);};
这里的CmdBuffer的数组CircledBuffer就是我基于char构建的tcp命令的接收缓冲区,首先session进入开始状态。
void session::_start() {started_=true;CmdBuffer* cmd;std::cout<<getRemoteAddr()<<":"<<getRemotePort()<<"is connected \n";cmd= readBuffer.GetLast();readBuffer.MoveNext();_setTimer(2);socket_.async_receive(boost::asio::buffer(cmd->data), strand_.wrap( boost::bind(&session::receive_handler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)));}
session的开始状态,是以receive开始的。收到数据后,调用receive_handler的函数。
void session::receive_handler(const boost::system::error_code &ec, std::size_t bytes_transferred) { if (ec){if (ec.value() == boost::asio::error::eof){stop();}return;} if (!started())return;processCmd(bytes_transferred);CmdBuffer* cmd;cmd= readBuffer.GetLast();readBuffer.MoveNext();socket_.async_receive(boost::asio::buffer(cmd->data), strand_.wrap( boost::bind(&session::receive_handler, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred))); }
receive_handler是对收到的数据进行处理,调用processCmd来进行,processCmd仅仅做了printf,由于有buffer缓存,可以根据分隔符来处理命令,处理完数据后,继续接收数据,继续调用async_receive的方法,构成了回调的循环结构。
对于数据的发送,是通过上层函数发起的,session的上层接口是channel,只需要留出发送数据的接口就可以了。
void session::_start_send(char* cmd) { char* wBufferPtr = (char*)write_buffer;memset(wBufferPtr,0,max_msg);sprintf(wBufferPtr,"%s\r\n",cmd);socket_.async_send(boost::asio::buffer(write_buffer,strlen(wBufferPtr)),strand_.wrap( boost::bind(&session::send_handler, shared_from_this(), boost::asio::placeholders::error))); }
对于send_handler,是发送之后做的处理,这里可以为空就可以了。
最后,介绍一下boost在网络编程中,需要用到的endpoint的类,这个类的作用相当于sockaddr_in,提供一些端口,ip等信息。
获取远端的ip和端口的方法:
boost::asio::ip::tcp::endpoint remoteEp = socket_.remote_endpoint(); ip = remoteEp.address().to_string();port = remoteEp.port()
一会儿,我再整理一下tcp服务器中,比较实用的串行化工具strand和异步定时器。
全部源代码下载连接在这里
阅读全文
0 0
- boost用asio设计TCP服务器中单连接的设计
- boost用asio设计TCP服务器的关键技术
- 基于Boost.Asio的异步通信服务器设计与开发
- Boost.Asio 设计索引
- boost中asio的tcp::iostream例子
- Boost Asio 异步TCP服务器框架
- boost asio的异步服务器
- Boost.asio 0.37设计笔记(翻译)
- boost::asio tcp socket 的使用示例
- boost::asio::ip::tcp::resolver的故事
- boost asio 单线程的异步
- boost::asio::tcp
- boost设计TCP服务器中的strand与心跳机制实现
- 设计TCP服务器的规则
- 使用boost ASIO库封装TCP服务器类
- Boost::Asio一个简单的Echo服务器
- boost::asio一个简单的echo服务器
- Boost::Asio一个简单的Echo服务器
- pycharm与webstorm 2017 激活破解
- 三种undo/Redo的实现
- SDOI2009晨跑
- Docker个人学习总结
- 图像压缩中的一些概念(码率截取,位平面,码率分配,小波提升)
- boost用asio设计TCP服务器中单连接的设计
- 网页启动App并传值
- android studio/ecplice全世界最实用的快捷键
- B树的插入、删除操作
- python打包(.py转换exe)
- 25.七-计算器类
- 关于JAVA中怎么读取和修改.properties文件中的值
- 舞动海报
- mybatis中 #$ 注入参数的不同