无论做什么事情,每个人都有自己的喜好。比如写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(); }
因为很简单就没有必要做多余的解释了哈。