boost::asio編程-同步TCP
boost.asio庫是一個(gè)跨平臺(tái)的網(wǎng)絡(luò)及底層IO的C++編程庫,它使用現(xiàn)代C++手法實(shí)現(xiàn)了統(tǒng)一的異步調(diào)用模型。
boost.asio庫支持TCP、UDP、ICMP通信協(xié)議。
下面介紹同步TCP模式:
大家好!我是同步方式!
我的主要特點(diǎn)就是執(zhí)著!所有的操作都要完成或出錯(cuò)才會(huì)返回,不過偶的執(zhí)著被大家稱之為阻塞,實(shí)在是郁悶~~(場(chǎng)下一片噓聲),其實(shí)這樣 也是有好處的,比如邏輯清晰,編程比較容易。
在服務(wù)器端,我會(huì)做個(gè)socket交給acceptor對(duì)象,讓它一直等客戶端連進(jìn)來,連上以后再通過這個(gè)socket與客戶端通信, 而所有的通信都是以阻塞方式進(jìn)行的,讀完或?qū)懲瓴艜?huì)返回。
在客戶端也一樣,這時(shí)我會(huì)拿著socket去連接服務(wù)器,當(dāng)然也是連上或出錯(cuò)了才返回,最后也是以阻塞的方式和服務(wù)器通信。
有人認(rèn)為同步方式?jīng)]有異步方式高效,其實(shí)這是片面的理解。在單線程的情況下可能確實(shí)如此,我不能利用耗時(shí)的網(wǎng)絡(luò)操作這段時(shí)間做別的事 情,不是好的統(tǒng)籌方法。不過這個(gè)問題可以通過多線程來避免,比如在服務(wù)器端讓其中一個(gè)線程負(fù)責(zé)等待客戶端連接,連接進(jìn)來后把socket交給另外的線程去 和客戶端通信,這樣與一個(gè)客戶端通信的同時(shí)也能接受其它客戶端的連接,主線程也完全被解放了出來。
我的介紹就有這里,謝謝大家!
同步方式示例代碼:
服務(wù)器端
// BoostTcpServer.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 //  #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對(duì)象   io_service iosev;    //創(chuàng)建用于接收客戶端連接的acceptor對(duì)象 #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對(duì)象     ip::tcp::socket socket(iosev);     // 等待直到客戶端連接進(jìn)來     acceptor.accept(socket);     // 顯示連接進(jìn)來的客戶端     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)//收到結(jié)束消息結(jié)束客戶端連接       {         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();     // 與當(dāng)前客戶交互完成后循環(huán)繼續(xù)等待下一客戶連接   }   return 0; } 客戶端
// BoostTcpClient.cpp : 定義控制臺(tái)應(yīng)用程序的入口點(diǎn)。 //  #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對(duì)象   io_service iosev;   // socket對(duì)象   ip::tcp::socket socket(iosev);    // 連接端點(diǎn),這里使用了本機(jī)連接,可以修改IP地址測(cè)試遠(yuǎn)程連接 #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的本機(jī)回環(huán)地址,類似于"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);   // 連接服務(wù)器   boost::system::error_code ec;   socket.connect(ep,ec);   // 如果出錯(cuò),打印出錯(cuò)信息   if (ec)   {     std::cout << boost::system::system_error(ec).what() << std::endl;     return -1;   }    //循環(huán)發(fā)送和接收數(shù)據(jù)   for(int i=0;i<5;++i)   {     //發(fā)送數(shù)據(jù)     socket.write_some(buffer("hello"), ec);     // 接收數(shù)據(jù)     char buf[100];     size_t len=socket.read_some(buffer(buf), ec);     std::cout.write(buf, len);     Sleep(500);   }   //發(fā)送與服務(wù)端約定好的結(jié)束語,由服務(wù)端斷鏈   socket.write_some(buffer("bye"), ec);      getchar();   return 0; } 代碼中兼容了IPV4和IPV6兩種IP協(xié)議,使用宏定義選擇使用哪種IP協(xié)議,當(dāng)然客戶端和服務(wù)端的協(xié)議必須一致才能正常通信。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
新聞熱點(diǎn)
疑難解答