第一次写协程

  无论做什么事情,每个人都有自己的喜好。比如写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();
}

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

posted @ 2014-01-05 19:45  f_x_p  阅读(1839)  评论(0编辑  收藏  举报