程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> boost------asio庫的使用2(Boost程序庫完全開發指南)讀書筆記

boost------asio庫的使用2(Boost程序庫完全開發指南)讀書筆記

編輯:C++入門知識

網絡通信

asio庫支持TCP、UDP、ICMP通信協議,它在名字空間boost::asio::ip裡提供了大量的網絡通信方面的函數和類,很好地封裝了原始的Berkeley Socket Api,展現給asio用戶一個方便易用且健壯的網絡通信庫。

 


ip::tcp類是asio網絡通信(TCP)部分主要的類,但它本身並沒有太多的功能,而是定義了數個用於TCP通信的typedef類型,用來協作完成網絡通信。這些typedef包括端點類endpoint、套接字類socket、流類iostream,以及接收器acceptor、解析器resolver等等。從某種程度上來看,ip::tcp類更像是一個名字空間。

 

1、IP地址和端點
IP地址獨立於TCP、UDP等通信協議,asio庫使用類ip::address來表示IP地址,可以同時支持ipv4和ipv6兩種地址。

[cpp]
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    boost::asio::ip::address addr;          // 聲明一個ip地址對象  
    addr = addr.from_string("127.0.0.1");   // 從字符串產生IP地址  
    assert(addr.is_v4());                   // ipv4的地址  
    cout << addr.to_string() << endl; 
 
    addr = addr.from_string("2000:0000:0000:0000:0001:2345:6789:abcd"); 
    assert(addr.is_v6()); 
    cout << addr.to_string() << endl; 
 
    return 0; 

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 boost::asio::ip::address addr;   // 聲明一個ip地址對象
 addr = addr.from_string("127.0.0.1"); // 從字符串產生IP地址
 assert(addr.is_v4());     // ipv4的地址
 cout << addr.to_string() << endl;

 addr = addr.from_string("2000:0000:0000:0000:0001:2345:6789:abcd");
 assert(addr.is_v6());
 cout << addr.to_string() << endl;

 return 0;
}

 

有了IP地址,再加上通信用的端口號就構成了一個socket端點,在asio庫中用ip::tcp::endpoint類來表示。它的主要用法就是通過構造函數創建一個可用於socket通信的端點對象,端點的地址和端口號可以用address()和port()獲得:

 


[cpp]
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    boost::asio::ip::address addr;          // 聲明一個ip地址對象  
    addr = addr.from_string("127.0.0.1");   // 從字符串產生IP地址  
 
    boost::asio::ip::tcp::endpoint ep(addr, 6688); 
 
    assert(ep.address() == addr); 
    assert(ep.port() == 6688); 
 
    return 0; 

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 boost::asio::ip::address addr;   // 聲明一個ip地址對象
 addr = addr.from_string("127.0.0.1"); // 從字符串產生IP地址

 boost::asio::ip::tcp::endpoint ep(addr, 6688);

 assert(ep.address() == addr);
 assert(ep.port() == 6688);

 return 0;
}

 

 

2、同步socket處理

ip::tcp的內部類型socket、acceptor和resolver是asio庫TCP通信中最核心的一組類,它們封裝了socket的連接、斷開和數據收發功能,使用它們可以很容易地編寫出socket程序。

 


socket類是TCP通信的基本類,調用成員函數connect()可以連接到一個指定的通信端點,連接成功後用local_endpoint()和remote_endpoint()獲得連接兩端的端點信息,用read_some()和write_some()阻塞讀寫數據,當操作完成後使用close()函數關閉socket。如果不關閉socket,那麼在socket對象析構時也會自動調用close()關閉。

 


acceptor類對應socketAPI的accept()函數功能,它用於服務器端,在指定的端口號接受連接,必須配合socket類才能完成通信。

 


resolver類對應socketAPI的getaddrinfo()系列函數,用於客戶端解析網址獲得可用的IP地址,解析得到的IP地址可以使用socket對象連接。

 


下面是一個使用socket類和acceptor類來實現一對同步通信的服務器和客戶端程序:

服務器端(它使用一個acceptor對象在6688端口接受連接,當有連接時使用一個socket對象發送一個字符串):

 


server.cpp:

[cpp]
// server.cpp : 定義控制台應用程序的入口點。  
//  
 
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    try 
    { 
        cout << "server start" << endl; 
        boost::asio::io_service ios; 
 
        boost::asio::ip::tcp::acceptor acceptor(ios,  
            boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 6688)); 
 
        cout << acceptor.local_endpoint().address() << endl; 
 
        while (true) 
        { 
            boost::asio::ip::tcp::socket sock(ios); 
            acceptor.accept(sock); 
 
            cout << "client : "; 
            cout << sock.remote_endpoint().address() << endl; 
 
            sock.write_some(boost::asio::buffer("hello asio")); 
        } 
    } 
 
    catch (std::exception& e) 
    { 
        cout << e.what() << endl; 
    } 
 
    return 0; 

// server.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
 try
 {
  cout << "server start" << endl;
  boost::asio::io_service ios;

  boost::asio::ip::tcp::acceptor acceptor(ios,
   boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 6688));

  cout << acceptor.local_endpoint().address() << endl;

  while (true)
  {
   boost::asio::ip::tcp::socket sock(ios);
   acceptor.accept(sock);

   cout << "client : ";
   cout << sock.remote_endpoint().address() << endl;

   sock.write_some(boost::asio::buffer("hello asio"));
  }
 }

 catch (std::exception& e)
 {
  cout << e.what() << endl;
 }

 return 0;
}
服務器端程序裡要注意的是自由函數buffer(),他可以包裝很多種類的容器成為asio組件可用的緩沖區類型。通常不能直接把數組、vercor等容器用作asio的讀寫參數,必須使用buffer()函數包裝

 


client:

[cpp]
// client.cpp : 定義控制台應用程序的入口點。  
//  
 
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
#include "vector"  
 
 
class AsynTimer 

public: 
    template<typename F>                              // 模板類型,可以接受任意可調用物  
    AsynTimer(boost::asio::io_service& ios, int x, F func) 
        :f(func), count_max(x), count(0),               // 初始化回調函數和計數器  
        t(ios, boost::posix_time::millisec(500))        // 啟動計時器  
    { 
        t.async_wait(boost::bind(&AsynTimer::CallBack,  // 異步等待計時器  
            this, boost::asio::placeholders::error));   // 注冊回調函數  
    } 
 
    void CallBack(const boost::system::error_code& error) 
    { 
        if (count >= count_max)   // 如果計數器達到上限則返回  
        { 
            return; 
        } 
        ++count; 
        f();                     // 調用function對象  
 
        // 設置定時器的終止時間為0.5秒之後  
        t.expires_at(t.expires_at() + boost::posix_time::microsec(500)); 
        // 再次啟動定時器,異步等待  
        t.async_wait(boost::bind(&AsynTimer::CallBack, this, boost::asio::placeholders::error)); 
    } 
 
private: 
    int count; 
    int count_max; 
    boost::function<void()> f;        // function對象,持有無參無返回值的可調用物  
    boost::asio::deadline_timer t;  // asio定時器對象  
}; 
 
 
void client(boost::asio::io_service& ios) 

    try 
    { 
        cout << "client start." << endl; 
 
        boost::asio::ip::tcp::socket sock(ios); 
        boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 6688); 
 
        sock.connect(ep); 
 
        vector<char> str(100, 0); 
        sock.read_some(boost::asio::buffer(str)); 
 
        cout << "recive from" << sock.remote_endpoint().address(); 
        cout << &str[0] << endl; 
 
    } 
    catch (std::exception& e) 
    { 
        cout << e.what() << endl; 
    } 

 
 
int _tmain(int argc, _TCHAR* argv[]) 

    boost::asio::io_service ios; 
    AsynTimer at(ios, 50000, boost::bind(client, boost::ref(ios))); 
    ios.run(); 
 
    return 0; 

// client.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;
#include "vector"


class AsynTimer
{
public:
 template<typename F>        // 模板類型,可以接受任意可調用物
 AsynTimer(boost::asio::io_service& ios, int x, F func)
  :f(func), count_max(x), count(0),    // 初始化回調函數和計數器
  t(ios, boost::posix_time::millisec(500))  // 啟動計時器
 {
  t.async_wait(boost::bind(&AsynTimer::CallBack,  // 異步等待計時器
   this, boost::asio::placeholders::error)); // 注冊回調函數
 }

 void CallBack(const boost::system::error_code& error)
 {
  if (count >= count_max)  // 如果計數器達到上限則返回
  {
   return;
  }
  ++count;
  f();      // 調用function對象

  // 設置定時器的終止時間為0.5秒之後
  t.expires_at(t.expires_at() + boost::posix_time::microsec(500));
  // 再次啟動定時器,異步等待
  t.async_wait(boost::bind(&AsynTimer::CallBack, this, boost::asio::placeholders::error));
 }

private:
 int count;
 int count_max;
 boost::function<void()> f;  // function對象,持有無參無返回值的可調用物
 boost::asio::deadline_timer t; // asio定時器對象
};


void client(boost::asio::io_service& ios)
{
 try
 {
  cout << "client start." << endl;

  boost::asio::ip::tcp::socket sock(ios);
  boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 6688);

  sock.connect(ep);

  vector<char> str(100, 0);
  sock.read_some(boost::asio::buffer(str));

  cout << "recive from" << sock.remote_endpoint().address();
  cout << &str[0] << endl;

 }
 catch (std::exception& e)
 {
  cout << e.what() << endl;
 }
}


int _tmain(int argc, _TCHAR* argv[])
{
 boost::asio::io_service ios;
 AsynTimer at(ios, 50000, boost::bind(client, boost::ref(ios)));
 ios.run();

 return 0;
}


3、異步socket處理
我們把剛才的同步socket程序改為異步調用方式。異步程序的處理流程與同步程序基本相同,只需要把原有的同步調用函數都換成前綴是async_的異步調用函數,並增加回調函數,在回調函數中再啟動一個異步調用

 


服務器端:

[cpp]
// server.cpp : 定義控制台應用程序的入口點。  
//  
 
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
 
 
class Server 

private: 
    boost::asio::io_service& ios; 
    boost::asio::ip::tcp::acceptor acceptor; 
    typedef boost::shared_ptr<boost::asio::ip::tcp::socket> sock_pt; 
 
public: 
    Server(boost::asio::io_service& io) : ios(io), 
        acceptor(ios, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 6688)) 
    { 
        Start(); 
    } 
    ~Server() 
    { 
 
    } 
 
    void Start() 
    { 
        sock_pt sock(new boost::asio::ip::tcp::socket(ios));    // 智能指針  
 
        // 異步偵聽服務  
        acceptor.async_accept(*sock, boost::bind(&Server::acceptor_handle,  
                                                 this, boost::asio::placeholders::error, sock)); 
    } 
 
    void acceptor_handle(const boost::system::error_code& error, sock_pt sock) 
    { 
        if (error) 
        { 
            return; 
        } 
        cout << "client : "; 
 
        // 輸出連接的客戶端信息  
        cout << sock->remote_endpoint().address() << endl; 
 
        //   
        sock->async_write_some( boost::asio::buffer("hello asio"),  
                                boost::bind(&Server::write_handle, 
                                this, boost::asio::placeholders::error)); 
 
        Start(); // 再次啟動異步接受連接  
    } 
 
    void write_handle(const boost::system::error_code& error) 
    { 
        cout << "send message is complate" << endl; 
    } 
 
}; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    try 
    { 
        cout << "server start." << endl; 
 
        boost::asio::io_service ios; 
 
        Server serv(ios); 
 
        ios.run(); 
    } 
    catch (std::exception& e) 
    { 
        cout << e.what() << endl; 
    } 
 
    return 0; 

// server.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;


class Server
{
private:
 boost::asio::io_service& ios;
 boost::asio::ip::tcp::acceptor acceptor;
 typedef boost::shared_ptr<boost::asio::ip::tcp::socket> sock_pt;

public:
 Server(boost::asio::io_service& io) : ios(io),
  acceptor(ios, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 6688))
 {
  Start();
 }
 ~Server()
 {

 }

 void Start()
 {
  sock_pt sock(new boost::asio::ip::tcp::socket(ios)); // 智能指針

  // 異步偵聽服務
  acceptor.async_accept(*sock, boost::bind(&Server::acceptor_handle,
             this, boost::asio::placeholders::error, sock));
 }

 void acceptor_handle(const boost::system::error_code& error, sock_pt sock)
 {
  if (error)
  {
   return;
  }
   cout << "client : ";

  // 輸出連接的客戶端信息
   cout << sock->remote_endpoint().address() << endl;

  //
   sock->async_write_some( boost::asio::buffer("hello asio"),
         boost::bind(&Server::write_handle,
         this, boost::asio::placeholders::error));

  Start(); // 再次啟動異步接受連接
 }

 void write_handle(const boost::system::error_code& error)
 {
  cout << "send message is complate" << endl;
 }

};


int _tmain(int argc, _TCHAR* argv[])
{
 try
 {
  cout << "server start." << endl;

  boost::asio::io_service ios;

  Server serv(ios);

  ios.run();
 }
 catch (std::exception& e)
 {
  cout << e.what() << endl;
 }

 return 0;
}


首先檢查asio傳遞的error_code,保證沒有錯誤發生。然後調用socket對象的async_write_some()異步發送數據。同樣,我們必須再為這個異步調用編寫回調函數write_handler()。當發送完數據後不要忘記調用Start()再次啟動服務器接受鏈接,否則當完成數據發送後io_service將因為沒有時間處理而結束運行。

 


發送數據的回調函數write_handler()很簡單,因為不需要做更多的工作,可以直接實現一個空函數,在這裡簡單地輸出一條信息,表示異步發送數據完成

 


客戶端:

[cpp]
// client.cpp : 定義控制台應用程序的入口點。  
//  
 
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "iostream"  
using namespace std; 
#include "vector"  
 
 
class Client 

private: 
    boost::asio::io_service& ios; 
    boost::asio::ip::tcp::endpoint ep;  // tcp端點  
    typedef boost::shared_ptr<boost::asio::ip::tcp::socket> sock_pt; 
 
public: 
    Client(boost::asio::io_service& io) : ios(io), 
        ep(boost::asio::ip::address::from_string("127.0.0.1"), 6688) 
    { 
        Start(); // 啟動異步連接  
    } 
 
    ~Client() 
    { 
 
    } 
 
    void Start() 
    { 
        sock_pt sock(new boost::asio::ip::tcp::socket(ios)); 
        sock->async_connect(ep, boost::bind(&Client::conn_handle, this, 
                                            boost::asio::placeholders::error, sock)); 
    } 
 
    void conn_handle(const boost::system::error_code& error, sock_pt sock) 
    { 
        if (error) 
        { 
            return; 
        } 
        cout << "recive from : " << sock->remote_endpoint().address(); 
 
        // 建立接收數據的緩沖區  
        boost::shared_ptr<vector<char> > str(new vector<char>(100, 0)); 
 
        // 異步讀取數據  
        sock->async_read_some(boost::asio::buffer(*str), boost::bind(&Client::read_handle, 
                                                                    this,  
                                                                    boost::asio::placeholders::error, 
                                                                    str)); 
        Start(); // 再次啟動異步連接  
    } 
 
    void read_handle(const boost::system::error_code& error,  
                     boost::shared_ptr<vector<char> > str) 
    { 
        if (error) 
        { 
            return; 
        } 
        cout << &(*str)[0] << endl; 
    } 
}; 
 
 
int _tmain(int argc, _TCHAR* argv[]) 

    try 
    { 
        cout << "client start." << endl; 
        boost::asio::io_service ios; 
 
        Client client(ios); 
 
        ios.run(); 
    } 
    catch (std::exception& e) 
    { 
        cout << e.what() << endl; 
    } 
 
    return 0; 

// client.cpp : 定義控制台應用程序的入口點。
//

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "iostream"
using namespace std;
#include "vector"


class Client
{
private:
 boost::asio::io_service& ios;
 boost::asio::ip::tcp::endpoint ep; // tcp端點
 typedef boost::shared_ptr<boost::asio::ip::tcp::socket> sock_pt;

public:
 Client(boost::asio::io_service& io) : ios(io),
  ep(boost::asio::ip::address::from_string("127.0.0.1"), 6688)
 {
  Start(); // 啟動異步連接
 }

 ~Client()
 {

 }

 void Start()
 {
  sock_pt sock(new boost::asio::ip::tcp::socket(ios));
  sock->async_connect(ep, boost::bind(&Client::conn_handle, this,
           boost::asio::placeholders::error, sock));
 }

 void conn_handle(const boost::system::error_code& error, sock_pt sock)
 {
  if (error)
  {
   return;
  }
  cout << "recive from : " << sock->remote_endpoint().address();

  // 建立接收數據的緩沖區
  boost::shared_ptr<vector<char> > str(new vector<char>(100, 0));

  // 異步讀取數據
  sock->async_read_some(boost::asio::buffer(*str), boost::bind(&Client::read_handle,
                 this,
                 boost::asio::placeholders::error,
                 str));
  Start(); // 再次啟動異步連接
 }

 void read_handle(const boost::system::error_code& error,
      boost::shared_ptr<vector<char> > str)
 {
  if (error)
  {
   return;
  }
  cout << &(*str)[0] << endl;
 }
};


int _tmain(int argc, _TCHAR* argv[])
{
 try
 {
  cout << "client start." << endl;
  boost::asio::io_service ios;

  Client client(ios);

  ios.run();
 }
 catch (std::exception& e)
 {
  cout << e.what() << endl;
 }

 return 0;
}

 

 

4、查詢網絡地址
之前關於tcp通信的所有論述都是使用直接的ip地址,但在實際生活中大多數時候,都不大可能知道socket鏈接另一端的地址,而只有一個域名,這時候我們就需要使用resolver類來通過域名獲得可用的ip,它可以實現與ip版本無關的網址解析

 


resolver使用內部類query和iterator共同完成查詢ip地址的工作:首先使用網址和服務名創建query對象,然後由resolve()函數生成iterator對象,它代表了查詢到的ip端點。之後就可以使用socket對象嘗試連接,知道找到一個可用的為止。

[cpp]
#include "stdafx.h"  
#include "boost/asio.hpp"  
#include "boost/date_time/posix_time/posix_time.hpp"  
#include "boost/bind.hpp"  
#include "boost/function.hpp"  
#include "boost/lexical_cast.hpp"  
#include "boost/asio/error.hpp"  
#include "iostream"  
using namespace std; 
 
 
void resolv_connect(boost::asio::ip::tcp::socket& sock, const char* name, int port) 

    boost::asio::ip::tcp::resolver rlv(sock.get_io_service()); 
    boost::asio::ip::tcp::resolver::query qry(name, boost::lexical_cast<string>(port)); 
 
    boost::asio::ip::tcp::resolver::iterator iter = rlv.resolve(qry); 
    boost::asio::ip::tcp::resolver::iterator end; 
 
    boost::system::error_code ec = boost::asio::error::host_not_found; 
    for (; ec && iter != end; ++iter) 
    { 
        sock.close(); 
        sock.connect(*iter, ec); 
    } 
 
    if (ec) 
    { 
        cout << "can't connect." << endl; 
        throw boost::system::error_code(ec); 
    } 
 
    cout << "connet suceessd." << endl; 

 
 
int _tmain(int argc, _TCHAR* argv[]) 

    try 
    { 
        boost::asio::io_service ios; 
        boost::asio::ip::tcp::socket sock(ios); 
 
        resolv_connect(sock, "www.boost.org", 80); 
 
        ios.run(); 
    } 
    catch (std::exception& e) 
    { 
        cout << e.what() << endl; 
    } 
     
    return 0; 

#include "stdafx.h"
#include "boost/asio.hpp"
#include "boost/date_time/posix_time/posix_time.hpp"
#include "boost/bind.hpp"
#include "boost/function.hpp"
#include "boost/lexical_cast.hpp"
#include "boost/asio/error.hpp"
#include "iostream"
using namespace std;


void resolv_connect(boost::asio::ip::tcp::socket& sock, const char* name, int port)
{
 boost::asio::ip::tcp::resolver rlv(sock.get_io_service());
 boost::asio::ip::tcp::resolver::query qry(name, boost::lexical_cast<string>(port));

 boost::asio::ip::tcp::resolver::iterator iter = rlv.resolve(qry);
 boost::asio::ip::tcp::resolver::iterator end;

 boost::system::error_code ec = boost::asio::error::host_not_found;
 for (; ec && iter != end; ++iter)
 {
  sock.close();
  sock.connect(*iter, ec);
 }

 if (ec)
 {
  cout << "can't connect." << endl;
  throw boost::system::error_code(ec);
 }

 cout << "connet suceessd." << endl;
}


int _tmain(int argc, _TCHAR* argv[])
{
 try
 {
  boost::asio::io_service ios;
  boost::asio::ip::tcp::socket sock(ios);

  resolv_connect(sock, "www.boost.org", 80);

  ios.run();
 }
 catch (std::exception& e)
 {
  cout << e.what() << endl;
 }
 
 return 0;
}


resolv_connect()函數中使用lexical_cast,這是因為query對象只接受字符串參數,所以我們需要把端口號由整數轉換為字符串。

 


當開始resolver的迭代時,需要使用error_code和逾尾迭代器兩個條件來控制循環,因為有可能迭代完所有解析到的端點都無法連接,只有當error_code為0才表示連接成功。

 


有了resolv_connect()函數,就可以不受具體ip地址值的限制,以更直觀更靈活的域名來連接服務器。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved