C++ boost::asio編程-同步TCP詳解及執行個體代碼

來源:互聯網
上載者:User
boost::asio編程-同步TCP

boost.asio庫是一個跨平台的網路及底層IO的C++編程庫,它使用現代C++手法實現了統一的非同步呼叫模型。

boost.asio庫支援TCP、UDP、ICMP通訊協定。

下面介紹同步TCP模式:

大家好!我是同步方式!

我的主要特點就是執著!所有的操作都要完成或出錯才會返回,不過偶的執著被大家稱之為阻塞,實在是鬱悶~~(場下一片噓聲),其實這樣 也是有好處的,比如邏輯清晰,編程比較容易。

在伺服器端,我會做個socket交給acceptor對象,讓它一直等用戶端連進來,連上以後再通過這個socket與用戶端通訊, 而所有的通訊都是以阻塞方式進行的,讀完或寫完才會返回。

在用戶端也一樣,這時我會拿著socket去串連伺服器,當然也是連上或出錯了才返回,最後也是以阻塞的方式和伺服器通訊。
有人認為同步方式沒有非同步方式高效,其實這是片面的理解。在單線程的情況下可能確實如此,我不能利用耗時的網路操作這段時間做別的事 情,不是好的統籌方法。不過這個問題可以通過多線程來避免,比如在伺服器端讓其中一個線程負責等待用戶端串連,串連進來後把socket交給另外的線程去 和用戶端通訊,這樣與一個用戶端通訊的同時也能接受其它用戶端的串連,主線程也完全被解放了出來。

我的介紹就有這裡,謝謝大家!

同步方式範例程式碼:

伺服器端

// BoostTcpServer.cpp : 定義控制台應用程式的進入點。 //    #include "stdafx.h" #include "boost/asio.hpp" #include "boost/thread.hpp"    using namespace std; using namespace boost::asio;    #ifdef _MSC_VER #define _WIN32_WINNT  0X0501 //避免VC下編譯警告 #endif    #define PORT 1000 #define IPV6 //#define IPV4    int _tmain(int argc, _TCHAR* argv[]) {   // 所有asio類都需要io_service對象   io_service iosev;      //建立用於接收用戶端串連的acceptor對象 #ifdef IPV4   ip::tcp::acceptor acceptor(iosev,ip::tcp::endpoint(ip::tcp::v4(), PORT)); #endif    #ifdef IPV6   ip::tcp::acceptor acceptor(iosev,ip::tcp::endpoint(ip::tcp::v6(), PORT)); #endif      while (true)   {     // socket對象     ip::tcp::socket socket(iosev);     // 等待直到用戶端串連進來     acceptor.accept(socket);     // 顯示串連進來的用戶端     std::cout <<"remote ip:"<<socket.remote_endpoint().address()<<endl;     std::cout <<"remote port:"<<socket.remote_endpoint().port() << std::endl;        char buf[2048];     boost::system::error_code ec;     while(1)     {       socket.read_some(buffer(buf),ec);       if (ec)       {         std::cout <<boost::system::system_error(ec).what() << std::endl;         break ;       }       std::cout<<"recv msg:"<<buf<<endl;       if(strcmp(buf,"bye")==0)//收到結束訊息結束用戶端串連       {         break;       }       socket.write_some(buffer("I heared you!\n"),ec);       if (ec)       {         std::cout <<boost::system::system_error(ec).what() << std::endl;         break ;       }     }     socket.close();     // 與當前客戶互動完成後迴圈繼續等待下一客戶串連   }   return 0; }

用戶端

// BoostTcpClient.cpp : 定義控制台應用程式的進入點。 //    #include "stdafx.h" #include "boost/asio.hpp"    using namespace boost::asio;    #ifdef _MSC_VER #define _WIN32_WINNT  0X0501 //避免VC下編譯警告 #endif    #define PORT 1000 #define IPV6 //#define IPV4    int _tmain(int argc, _TCHAR* argv[]) {   // 所有asio類都需要io_service對象   io_service iosev;   // socket對象   ip::tcp::socket socket(iosev);      // 串連端點,這裡使用了本機串連,可以修改IP地址測試遠端連線 #ifdef IPV4   ip::address_v4 address=ip::address_v4::from_string("127.0.0.1"); #endif    #ifdef IPV6   //"0:0:0:0:0:0:0:1"為IPV6的本機迴環地址,類似於"127.0.0.1"   ip::address_v6 address=ip::address_v6::from_string("0:0:0:0:0:0:0:1"); #endif   ip::tcp::endpoint ep(address, PORT);   // 串連伺服器   boost::system::error_code ec;   socket.connect(ep,ec);   // 如果出錯,列印出錯資訊   if (ec)   {     std::cout << boost::system::system_error(ec).what() << std::endl;     return -1;   }      //迴圈發送和接收資料   for(int i=0;i<5;++i)   {     //發送資料     socket.write_some(buffer("hello"), ec);     // 接收資料     char buf[100];     size_t len=socket.read_some(buffer(buf), ec);     std::cout.write(buf, len);     Sleep(500);   }   //發送與服務端約定好的結束語,由服務端斷鏈   socket.write_some(buffer("bye"), ec);        getchar();   return 0; }

代碼中相容了IPV4和IPV6兩種IP協議,使用宏定義選擇使用哪種IP協議,當然用戶端和服務端的協議必須一致才能正常通訊。

感謝閱讀,希望能協助到大家,更多相關文章請關注topic.alibabacloud.com(www.php.cn) !

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.