zoukankan      html  css  js  c++  java
  • 第一次写协程

      无论做什么事情,每个人都有自己的喜好。比如写C++程序,有的人喜欢用面向过程的思路写,有的人喜欢用面向对象,有的人喜欢模板等等,microcai老师喜欢用协程,因为他喜欢用异步IO,而异步会带来代码的混乱,可读性变差的缺点,但有了协程这个好东西则会让你用同步的思路去写异步。菜菜老师甚至开始迷恋起协程了,今天他给我们布置了个作业,用协程的方法来实现echo服务器。我花了点时间随便写了小程序,当然也是第一次使用协程玩意,留一个纪念吧,哈哈。

      

    #include <boost/asio.hpp>
    #include <boost/asio/coroutine.hpp>
    #include <boost/enable_shared_from_this.hpp>
    #include <boost/shared_ptr.hpp>
    #include <boost/system/system_error.hpp>
    #include <functional>
    #include <iostream>
    #include <string>
    #include <algorithm>
    using namespace boost::asio;
    using namespace std::placeholders;
    io_service ioservice;
    ip::tcp::acceptor acceptor(ioservice,ip::tcp::endpoint(ip::tcp::v4(),27017));
    
    class service_to_client:public boost::enable_shared_from_this<service_to_client>
    {
    public:
        service_to_client():sock_(ioservice),status_(false)
        {
            memset(read_buf_,0,sizeof(read_buf_));
        }    
    
        void start()
        {
            status_=true;
        }
    
        void close_connect()
        {
            status_=false;
            sock_.close();        
        } 
    
        ip::tcp::socket& sock()
        {
            return sock_;
        }
    public:
        char read_buf_[1024];
        ip::tcp::socket sock_;
        bool status_;
    };
    
    class service_to_client_loop_op:public boost::asio::coroutine
    {
    public:
    service_to_client_loop_op(io_service& _io_service,boost::shared_ptr<service_to_client> _client)
        :m_client_(_client),m_service_(_io_service)
    {
        m_service_.post(boost::asio::detail::bind_handler(*this,boost::system::error_code(),0));    
    }
    
    void operator()(const boost::system::error_code& ec,size_t bytes_transferred)
    {
            
        if(ec == boost::system::errc::operation_canceled) return;
        
        BOOST_ASIO_CORO_REENTER(this)
        {
            while(m_client_->status_)
            {
    
                BOOST_ASIO_CORO_YIELD m_client_->sock_.async_read_some(buffer(m_client_->read_buf_),*this);
                if(ec)
                {
                    std::cout<<"async_read() failed!"<<std::endl;        
                    m_client_->close_connect();
                    return;
                }
                std::cout<<m_client_->read_buf_;
                BOOST_ASIO_CORO_YIELD async_write(m_client_->sock_,buffer(m_client_->read_buf_),*this);
                if(ec)
                {
                    std::cout<<"async_write() failed!"<<std::endl;        
                    m_client_->close_connect();
                    return;    
                }
                
            }    
        }
    }
    private:
    boost::shared_ptr<service_to_client> m_client_;    
    io_service& m_service_;
    };
    
    static service_to_client_loop_op make_main_loop(io_service& _io_service,boost::shared_ptr<service_to_client> _client)
    {
        return service_to_client_loop_op(_io_service,_client);
    }
    
    
    void loop_start(boost::shared_ptr<service_to_client> client_ptr)
    {
        client_ptr->start();
        make_main_loop(ioservice,client_ptr);
    }
    void accept_handler(boost::shared_ptr<service_to_client> client_ptr,const boost::system::error_code& ec)
    {
        loop_start(client_ptr);
        std::cout<<"...somebody is coming...."<<std::endl;
    
        boost::shared_ptr<service_to_client> new_client(new service_to_client);
        acceptor.async_accept(new_client->sock(),std::bind(accept_handler,new_client,_1));
    }
    
    int main()
    {
        boost::shared_ptr<service_to_client> client_ptr(new service_to_client);
        acceptor.async_accept(client_ptr->sock(),std::bind(accept_handler,client_ptr,_1));
        ioservice.run();
    }

    因为很简单就没有必要做多余的解释了哈。

  • 相关阅读:
    OEP
    壳的执行过程
    JavaScript RSA算法简单实现(转)
    创建根证书及其子证书
    从零开始学习Sencha Touch MVC应用之十四
    javascript base64
    discuz 文档地址
    虚拟机共享数据
    转Javascript到PHP RSA加密通讯的简单实现
    PHP RSA研究
  • 原文地址:https://www.cnblogs.com/fxplove/p/3506181.html
Copyright © 2011-2022 走看看