zoukankan      html  css  js  c++  java
  • [Boost基础]并发编程——asio网络库——异步socket处理

    异步服务器端

    #include <conio.h>
    #include <iostream>
    using namespace std;
    #include <boost/asio.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/bind.hpp>
    using namespace boost;
    using namespace boost::asio;
    void test1(){}
    //异步server
    //异步程序的处理流程与同步程序基本相同,只需要把原有的同步调用函数都换成前缀是async_的异步调用函数,并增加回调函数,在回调函数中再启动一个异步调用。
    class server
    {
    private:
        io_service& ios;
        ip::tcp::acceptor acceptor;
        typedef shared_ptr<ip::tcp::socket> sock_pt;
    public:
        server(io_service& io):ios(io),acceptor(ios,ip::tcp::endpoint(ip::tcp::v4(),6688))
        {
            start();
        }
        void start()
        {
            sock_pt sock(new ip::tcp::socket(ios));//智能指针
            acceptor.async_accept(*sock,bind(&server::accept_handler,this,placeholders::error,sock));//异步监听服务
            //start()函数用于启动异步接受连接,需要调用acceptor的async_accept()函数。为了能够让socket镀锡能够被异步调用后还能使用,我们必须使用shared_ptr来创建socket对象的智能指针,它可以再程序的整个生命周期中存在,直到没有人使用它为止。
        }
        //当有TCP连接发生时,server::accept_handler()函数将被调用,它使用socket对象发生数据。
        void accept_handler(const system::error_code& ec,sock_pt sock)
        {
            if (ec)//检测错误码
            {
                return;
            }
            cout<<"client:";//输出连接的客户端信息
            cout<<sock->remote_endpoint().address()<<" port:"<<sock->remote_endpoint().port()<<endl;
            sock->async_write_some(buffer("hello asio"),bind(&server::write_handler,this,placeholders::error));
            start();//再次启动异步接受连接
            //首先它必须检测asio传递的error_code,保证没有错误发生。然后调用socket对象的async_write_some()异步发生数据。同样,我们必须再为这个异步调用编写回调函数write_handler()。当发生完数据后不要忘了调用start()再次启动服务器接收连接,否则当完成数据发送后io_service将因为没有时间处理而结束运行。
        }
        void write_handler(const system::error_code&)
        {
            cout<<"send msg complete."<<endl;
        }
    };
    void test2()
    {
        try
        {
            cout<<"server start."<<endl;
            io_service ios;
            server serv(ios);
            ios.run();
        } 
        catch (std::exception& e)
        {
            cout<<e.what()<<endl;
        }
    } 
    void test(char t)  
    {  
        std::cout<<"press key====="<<t<<std::endl;  
        switch (t)  
        {    
        case '1':test1();break;   
        case '2':test2();break;     
        case 27:  
        case 'q':exit(0);break;  
        default: std::cout<<"default "<<t<<std::endl;break;  
        }  
    }  
    void main()
    {
        while (1)
        {
            test(getch());
        }
    }

    异步客户端

    #include <conio.h>
    #include <iostream>
    using namespace std;
    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    #include <boost/shared_ptr.hpp>
    using namespace boost;
    using namespace boost::asio;
    void test1(){}
    void test2(){}
    //异步client
    class client
    {
    private:
        io_service& ios;
        ip::tcp::endpoint ep;
        typedef shared_ptr<ip::tcp::socket> sock_pt;
    public:
        client(io_service& io):ios(io),ep(ip::address::from_string("127.0.0.1"),6688)
        {
            start();
        }
        void start()
        {
            sock_pt sock(new ip::tcp::socket(ios));//智能指针
            sock->async_connect(ep,bind(&client::conn_handler,this,placeholders::error,sock)); 
        } 
        void conn_handler(const system::error_code& ec,sock_pt sock)
        {
            if (ec)//检测错误码
            {
                return;
            }
            cout<<"recive from:";//输出连接的服务器端信息
            cout<<sock->remote_endpoint().address()<<" port:"<<sock->remote_endpoint().port()<<endl;
            shared_ptr<vector<char>>str(new vector<char>(100,0));//建立接收数据的缓冲区
            sock->async_read_some(buffer(*str),bind(&client::read_handler,this,placeholders::error,str));//异步读取数据
            start();// 再次启动异步连接
        }
        void read_handler(const system::error_code& ec,shared_ptr<vector<char>>str)
        {
            if (ec)
            {
                return;
            }
            cout<<&(*str)[0]<<endl;//输出接收的数据
        }
    };
    void test3()
    {
        try
        {
            cout<<"client start."<<endl;
            io_service ios;
            client cl(ios);
            ios.run();
        }  
        catch (std::exception& e)
        {
            cout<<e.what()<<endl;
        }
    }
    void test(char t)  
    {  
        std::cout<<"press key====="<<t<<std::endl;  
        switch (t)  
        {    
        case '1':test1();break;   
        case '2':test2();break;   
        case '3':test3();break;   
        case 27:  
        case 'q':exit(0);break;  
        default: std::cout<<"default "<<t<<std::endl;break;  
        }  
    }  
    void main()  
    {  
        while(1)   
            test(getch());   
    }  
    结果: 不停的执行
  • 相关阅读:
    【PASOTTIPASOTTI 伞】PASOTTI黑色聚酯纤维伞 Style 478
    乐雨 德国happyrain 超大男士高尔夫伞 直柄伞 双人伞 双层伞面防风雨伞 黑色【图片 价格 品牌 报价】-京东
    Larmes琅幕仕家居马头长款短柄自动雨伞 晴雨两用太阳伞防紫外线遮阳男士商务伞 雨伞雨具 骏马长款-金色配饰【图片 价格 品牌 报价】-京东
    Planner – 项目管理软件
    Project Server 2010安装部署手册(1.5版)
    Serena Software :: pod-update
    ]project-open[ 中国 功能一览
    几块钱或许能治好你的白发(2)
    爱心日式便当 给爸爸妈妈的爱心便当
    给老公做的爱心便当,持续更新!-西餐-19楼私房菜-杭州19楼
  • 原文地址:https://www.cnblogs.com/pangblog/p/3290043.html
Copyright © 2011-2022 走看看