Boost.Asio c++ 網路編程翻譯(23),boost.asio網路編程

來源:互聯網
上載者:User

Boost.Asio c++ 網路編程翻譯(23),boost.asio網路編程
用戶端應用中的非同步I/O主流程和同步用戶端應用有點類似,不同的是Boost.Asio每次都位於async_read和async_write請求中間。第一種情況是我在第四章 用戶端和服務端 中實現過的。你應該還記得在每個非同步作業結束的時候,我都啟動另外一個非同步作業,這樣service.run()方法才不會結束。為了適應第二種情況,你需要使用下面的程式碼片段:

void on_connect() {       do_read();
   }   void do_read() {
       async_read(sock_, buffer(read_buffer_),                   MEM_FN2(read_complete,_1,_2), MEM_FN2(on_read,_1,_2));
   }   void on_read(const error_code & err, size_t bytes) {
       if ( err) stop();       if ( !started() ) return;       std::string msg(read_buffer_, bytes);       if ( msg.find("clients") == 0) on_clients(msg);       else ...
   }   void on_clients(const std::string & msg) {
       std::string clients = msg.substr(8);       std::cout << username_ << ", new client list:" << clients ;       do_write("clients ok\n");

注意只要我們成功串連上,我們就開始從服務端讀取。每個on_[event]方法都會通過寫一個回複給服務端的方式來結束我們。使用非同步美好在於你可以使用Boost.Asio進行管理,從而把I/O網路操作和其他非同步作業結合起來。儘管它的流程不像同步的流程那麼清晰,你仍然可以用同步的方式來想象它。假設,你從一個web伺服器讀取檔案然後把它們儲存到一個資料庫中(非同步地)。你可以把這個過程想象成下面的流程圖:
服務端應用的非同步I/O現在要展示的是兩個普遍的情況,情況1(拉取)和情況2(推送)第一種情況同樣是我在第4章 用戶端和服務端中實現的非同步服務端。在每一個非同步作業最後,我都會啟動另外一個非同步作業,這樣的話service.run()久不會結束。現在要展示的是被剪裁過的架構代碼。下面是talk_to_client類所有的成員:
void start() {       ...
       do_read(); // first, we wait for client to login   }
   void on_read(const error_code & err, size_t bytes) {       std::string msg(read_buffer_, bytes);       if ( msg.find("login ") == 0) on_login(msg);       else if ( msg.find("ping") == 0) on_ping();

else ... }

   void on_login(const std::string & msg) {       std::istringstream in(msg);       in >> username_ >> username_;       do_write("login ok\n");
   }   void do_write(const std::string & msg) {
       std::copy(msg.begin(), msg.end(), write_buffer_);       sock_.async_write_some( buffer(write_buffer_, msg.size()),
                               MEM_FN2(on_write,_1,_2));
   }   void on_write(const error_code & err, size_t bytes) {

do_read(); } 

簡單來說,我們始終等待一個read操作,而且只要一發生,我們就處理然後將結果返回給用戶端。我們把上述代碼進行修改就可以完成一個推送服務端
void start() {       ...
       on_new_client_event();   }
   void on_new_client_event() {       std::ostringstream msg;       msg << "client count " << clients.size();       for ( array::const_iterator b = clients.begin(), e = clients.
   end();           (*b)->do_write(msg.str());

void on_read(const error_code & err, size_t bytes) {    std::string msg(read_buffer_, bytes);    // basically here, we only acknowledge    // that our clients received our notifications
}void do_write(const std::string & msg) {
    std::copy(msg.begin(), msg.end(), write_buffer_);    sock_.async_write_some( buffer(write_buffer_, msg.size()),
                            MEM_FN2(on_write,_1,_2));
}void on_write(const error_code & err, size_t bytes) {

do_read(); } 

只要有一個事件發生,我們假設是on_new_client_event,所有需要被通知到的用戶端都被發送一條資訊。當它們回複時,我們簡單認為他們已經確認收到事件。注意我們永遠不會把正在等待的非同步作業用盡(所以,service.run()不會結束),因為我們一直在等待一個新的用戶端:
ip::tcp::acceptor acc(service, ip::tcp::endpoint(ip::tcp::v4(),   8001));   void handle_accept(talk_to_client::ptr client, const error_code & err)   {
       client->start();       talk_to_client::ptr new_client = talk_to_client::new_();       acc.async_accept(new_client->sock(), bind(handle_accept,new_
   client,_1));   }








聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.