Boost Asio总结(17)心跳

1. 实现机制

定时器设定时间间隔向连接另一端发送心跳包,根据发送是否成功或者另一端的回复内容来判断连接是否中断,如果连接中断则关闭Socket再重新进行侦听或发起连接请求。

stpe1. 头文件定义timer

  
  boost::asio::steady_timer async_timer;

step2. cpp

void async_TcpClient::heartbeat() {
    std::cout<<"heartbeat!"<<std::endl;
    sendheart();
    timercontrol(true);
}

void async_TcpClient::sendheart() {

    //发送心跳
    boost::asio::async_write(socket,boost::asio::buffer("heart beating!"),
                             [this](boost::system::error_code ec, std::size_t t){
        if(!ec){
            std::cout<<"发送心跳"<<std::endl;
            readheart();
        } else{
            //失败时则进行断线重连
            reconnect();
        }
    });
}

void async_TcpClient::readheart() {
    std::string str;

    //读取回复
    boost::asio::async_read(socket,boost::asio::buffer(&str[0],2),
                            [this](boost::system::error_code ec, std::size_t t){
        if(!ec){
            if(!ec){//这里偷了个懒,实际上是要验证通信协议中心跳包的服务器响应数据
                std::cout<<"读取回复1"<<std::endl;
//              write();
            }else{
                std::cout<<"读取回复2"<<std::endl;
                //内容不符合则进行断线重连
                reconnect();
            }
        } else{
            std::cout<<"读取回复3"<<std::endl;
            //失败时则进行断线重连
            reconnect();
        }
   });
}

void async_TcpClient::reconnect() {
    socket.close();
    socket.async_connect(endpoint,[this](const boost::system::error_code ec){
        if(!ec){
            std::cout<<"reconnected!"<<std::endl;
        }else{
            std::cout<<"reconnect failed!"<<std::endl;
        }
    });
}

void async_TcpClient::timercontrol(const bool isInit) {
    if(isInit){
        async_timer.expires_from_now(std::chrono::seconds(10));
        async_timer.async_wait([this](const boost::system::error_code& ec){
            //这里就是用来被取消的,不需要任何进行操作
        });
    }

    //每次io操作时重置定时器计时,重置时应该保证async_wait已存在
    if(async_timer.expires_from_now(std::chrono::seconds(10))>0){
        async_timer.async_wait([this](const boost::system::error_code& ec){
            if (ec != boost::asio::error::operation_aborted)
            {
                heartbeat();
            } else{
                std::cout<<"another async_timer error2 "<<ec.message()<<std::endl;
            }
        });
    } else{
        std::cout<<"1async_timer error "<<std::endl;
    }
}

【引用】

[1] 代码async/client/tcpClient.cpp

st_asio_wrapper是一组类库,功能是对boost.asio的包装(调试环境:boost-1.51.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步(当然这是从boost.asio继承而来)、自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 2.3版更新内容: 消息(std::string包装)不再用boost::shared_ptr包装,之前有过度使用智能指针之嫌。效率上,std::string如果支持引用记数,或者编译器支持std::move语义,是没有损失的(因为也不存在内存的拷贝,反而省了智能指针使用上的开销),幸好vc支持std::move语义(虽然它不支持引用记数,linux则都支持)。这样带来一个问题,原来所有的接口中的boost::shared_ptr<std::string>数据类型,全部换成了std::string引用,升级到2.3的朋友要注意修改之前重写虚函数的签名,如果不改,则重写肯定不生效,变成了新增加虚函数了(因为签名不一样)。这样向大家道歉,接口签名以后应该不会变化了,但可能增加接口; 修复使用std::advance的一个BUG,此BUG在linux下不存在,这里顺便向大家说一下,std::advance在vc和gcc下面,语义一样,但处理方式有些不同,一定要注意; 增加了个专门用于服务端压力测试的客户端框架st_test_client,并写了一个demo test_client,可以在performance_test目录下面找到; 把连接服务端逻辑从st_client剥离出来,定义了一个新的类st_connector,st_client和st_test_client将从它继承; 增加对vc2010的支持,和编译时对编译器版本的检测,如果达不到vc2010及其以上的版本,st_asio_wrapper将直接报错。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

thefist11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值