c++11 boost - asio

2018-07-14 12:10:53

asio 库基于操作系统提供的异步机制,全程非阻塞,可以完全的利用cpu。在 linux 上内部实现基于 epoll。

asio-定时器

// Copyright (c) 2015
// Author: Chrono Law
#include <iostream>
//using namespace std;
using std::cout;
using std::endl;

#define BOOST_ASIO_DISABLE_STD_CHRONO
//#define BOOST_ASIO_ENABLE_HANDLER_TRACKING
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
//#include <boost/asio/use_future.hpp>
using namespace boost::asio;
using namespace boost::system;
using boost::function;

#include <boost/chrono.hpp>
using namespace boost::chrono;
seconds operator"" _s(unsigned long long n)
{
    return seconds(n);
}

milliseconds operator"" _ms(unsigned long long n)
{
    return milliseconds(n);
}

//同步定时器-阻塞
void case1()
{
    io_service io;

    steady_timer t(io, 500_ms);
    cout << t.expires_at() << endl;  //查看终止的时间点-纳秒
    cout << t.expires_from_now() << endl;  //查看时间长度-纳秒

    t.wait(); //阻塞等待定时器到期
    cout << "hello asio1" << endl;
}


//简单异步定时器-非阻塞
void case2()
{
    io_service io;

    steady_timer t(io, 500_ms);

    t.async_wait(
        [](const error_code& ec) {
            cout << "hello asio2" << endl;
        });

    io.run();
}

//可以定时执行任务的类
class timer_with_func
{
    typedef timer_with_func this_type;
private:
    int m_count = 0;  //当前
    int m_count_max = 0;   //上限
    function<void()> m_f;
    steady_timer m_t;
public:
    template<typename F> //模板类型,可以接受任意可调用物
    timer_with_func(io_service& io, int x, F func):
        m_count_max(x),  //初始化上限
        m_f(func), //初始化回调函数
        m_t(io, 0_s)  //启动计时器
    {
        m_t.async_wait(m_handler);
    }

private:
	//lambda
    typedef void(handler_type)(const error_code&);
    function<handler_type> m_handler =[&](const error_code&){
        if (m_count++ >= m_count_max){   return;  }
        m_f();

        m_t.expires_from_now(4_s);
        m_t.async_wait(m_handler);
    };

/* 利用bind
    void handler(const error_code&)
    {
        if (m_count++ >= m_count_max)
        {   return;  }

        m_f();

        m_t.expires_from_now(200_ms);
		
		//必须传递this指针,因为成员函数调用时默认第一个参数是this
        m_t.async_wait(bind(
                &this_type::handler, this,
                boost::asio::placeholders::error));
    }
*/
};

void case3()
{
    io_service io;

    timer_with_func t1(io, 5,[]{
    	cout << time(0) << endl;    	
    });

    io.run();
}

int main()
{
    //case1();
    //case2();
    case3();
}
[root@192 c++]# g++ -std=c++11 -L/usr/local/lib/boost_1_65_1/ -lboost_thread -lboost_system -lboost_chrono -lpthread  main.cpp
[root@192 c++]# ./a.out 
1531540612
1531540616
1531540620
1531540624
1531540628


下面实现了一个tcp服务器和定时器共存的例子。

#include <cstdlib>
#include <iostream>
#include <cstring>

#define BOOST_ASIO_DISABLE_STD_CHRONO

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <boost/asio.hpp>
#include <boost/asio/steady_timer.hpp>
//#include <boost/asio/use_future.hpp>
using namespace boost::asio;
using namespace boost::system;
using boost::function;

using std::cout; using std::endl;

#include <boost/chrono.hpp>
using namespace boost::chrono;
seconds operator"" _s(unsigned long long n)
{
    return seconds(n);
}

milliseconds operator"" _ms(unsigned long long n)
{
    return milliseconds(n);
}

void handle_write(const boost::system::error_code& error, ip::tcp::socket *sock, char *data);
void handle_read(const boost::system::error_code& error,size_t bytes_transferred, char *data, ip::tcp::socket *sock);
void start_accept();
void handle_accept(const boost::system::error_code& error, ip::tcp::socket *sock, char *data);


io_service io;
ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 8888); // 监听端口2001
ip::tcp::acceptor acc(io, ep);

void handle_write(const boost::system::error_code& error, ip::tcp::socket *sock, char *data){
    
    if(!error){
        memset(data, 0, strlen(data)+1);
        sock->async_read_some(buffer(data,512), boost::bind(handle_read, boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred, data, sock));
    }else{
        cout << "delete write" << endl;
        delete sock;
        delete data;
    }
}

void handle_read(const boost::system::error_code& error,size_t bytes_transferred, char *data, ip::tcp::socket *sock){
    
    if(data[0] == '\0'){
        cout << sock->remote_endpoint().address() << "-" << sock->remote_endpoint().port() << "closed" << endl;
        sock->close();
        delete sock;
        delete data;
        return;
    }
    
    if(data[0] != '\n'){
        cout << sock->remote_endpoint().address() << "-" << sock->remote_endpoint().port() << " get:" << data;
        async_write(*sock, buffer("yes", 512), boost::bind(handle_write, boost::asio::placeholders::error, sock, data));
    }else{
        memset(data, 0, strlen(data)+1);
        sock->async_read_some(buffer(data,512), boost::bind(handle_read, boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred, data, sock));
    }
    
    
}

void handle_accept(const boost::system::error_code& error, ip::tcp::socket *sock, char *data){
    if(!error){
        sock->async_read_some(buffer(data,512), boost::bind(handle_read, boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred, data, sock));
    }else{
        cout << "delete accept" << endl;
        delete sock;
        delete data;
    }
    
    start_accept();
    
}

void start_accept(){
    ip::tcp::socket * sock(new ip::tcp::socket(io));
    char *data = new char[512];
    
    acc.async_accept(*sock, boost::bind(handle_accept, boost::asio::placeholders::error, sock, data));
}

//可以定时执行任务的类
class timer_with_func
{
    typedef timer_with_func this_type;
private:
    int m_count = 0;  //当前
    function<void()> m_f;
    steady_timer m_t;
public:
    template<typename F> //模板类型,可以接受任意可调用物
    timer_with_func(io_service& io, F func):
        m_f(func), //初始化回调函数
        m_t(io, 0_s)  //启动计时器
    {
        m_t.async_wait(m_handler);
    }

private:
	//lambda
    typedef void(handler_type)(const error_code&);
    function<handler_type> m_handler =[&](const error_code&){
        m_f();

        m_t.expires_from_now(4_s);
        m_t.async_wait(m_handler);
    };
};

void sleep_func(){
	cout << time(0) << endl;
}

//多个异步例子
int main(int argc, char* argv[]){
    start_accept();
    
    timer_with_func t1(io, sleep_func);
    
    io.run();
    return 0;
}
[root@192 c++]# g++ -std=c++11 -L/usr/local/lib/boost_1_65_1/ \
                -lboost_thread -lboost_system -lboost_chrono -lpthread  main.cpp
[root@192 c++]# 
[root@192 c++]# 
[root@192 c++]# 
[root@192 c++]# ./a.out 
1531541232
1531541236
127.0.0.1-55584 get:hello
1531541240
1531541244
127.0.0.1-55584 get:www.freecls.com
127.0.0.1-55584closed
1531541248
[root@192 ~]# nc localhost 8888
hello
yes
www.freecls.com
yes


 备注

1.编译器版本gcc4.8.5,运行环境centos7 64位
2.本文只做简单记录用,详细用法请参考 Boost Library,或者是罗剑锋的 boost程序库完全开发指南 书本
3..原文地址http://www.freecls.com/a/2712/b6


©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。