boost::asio::ip::tcp::resolver解析

2014年4月16日 由 Creater 留言 »

Resolver是Asio的域名解析系统,它将指定的URL和服务转化为相应的ip和port的endpoint端点。

query指定主机与服务,比如

tcp::resolver::query query("www.unix8.net", "http");

endpoint指定主机IP地址与端口,比如

boost::asio::ip::address add;  
add = boost::asio::ip::address::from_string("222.216.160.69");
tcp::endpoint endpoint(add, 80);

//或者
tcp::endpoint endpoint(boost::asio::ip::address::from_string("222.216.160.69"), 80);

切记更新endpoint的第一个参数不能使用如下的方式

boost::asio::ip::address add;  
add.from_string("222.216.160.69");
tcp::endpoint endpoint(add, 80);

而要使用

boost::asio::ip::address add;  
add = add.from_string("222.216.160.69");
tcp::endpoint endpoint(add, 80);

或者上边说的方法,这是因为非静态的from_string返回的是一个临时对象,并不会修改add。

1.同步解析

同步解析共4个重载,返回值都为endpoint列表的头迭代器。

  1. 重载1,根据query来解析,未指定error_code
    iterator resolve(const query & q);

    出错会抛出异常。

  2. 重载2,指定query,指定error_cod
    iterator resolve(
        const query & q,
        boost::system::error_code & ec);

    出错会置error_code。
    以下两个重载函数为逆向解析。

  3. 重载3
    iterator resolve(
        const endpoint_type & e);

    根据endpoint逆向解析,出错抛出异常

  4. 重载4
    iterator resolve(
        const endpoint_type & e,
        boost::system::error_code & ec);

    根据endpoint逆向解析,出错置error_code.
    来看同步解析的例子

    #include "stdafx.h"
    #include <iostream>
    #include <boost/array.hpp>
    #include <boost/asio.hpp>
    #include <boost/bind.hpp>
    using boost::asio::ip::tcp;
    
    int main()
    {
    	try
    	{
    		boost::asio::io_service io_service;
    		tcp::resolver resolver(io_service);
    		tcp::resolver::query query("www.unix8.net", "http");
    		boost::system::error_code e;
    		tcp::resolver::iterator iter = resolver.resolve(query, e);
    		tcp::resolver::iterator end;
    		while (iter != end)
    		{
    			tcp::endpoint ep = *iter++;
    			std::cout<<ep<<std::endl;
    		}
    	}
    	catch (std::exception& e)
    	{
    		std::cerr << e.what() << std::endl;
    	}
    	system("pause");
    	return 0;
    }

2.异步解析

异步解析有两个重载,异步解析的结构是通过迭代器返回。

  1. 重载1,正向解析,根据query来解析。
    template<
        typename ResolveHandler>
    void-or-deduced async_resolve(
        const query & q,
        ResolveHandler handler);
    void handler(
      const boost::system::error_code& error, 
      resolver::iterator iterator          
    );
  2. 重载2,逆向解析
    template<
        typename ResolveHandler>
    void-or-deduced async_resolve(
        const endpoint_type & e,
        ResolveHandler handler);

    异步回调函数的需要如下的结构

    void handler(
      const boost::system::error_code& error,
      resolver::iterator iterator    
    );

    来看下异步解析的例子

    #include "stdafx.h"
    #include <iostream>
    #include <boost/array.hpp>
    #include <boost/asio.hpp>
    
    using boost::asio::ip::tcp;
    void printErr(const boost::system::error_code& error, tcp::resolver::iterator iter)
    {
    	if(!error)
    	{
    		tcp::resolver::iterator end;
    		while (iter != end)
    		{
    			tcp::endpoint endpoint = *iter++;
    			std::cout << endpoint << std::endl;
    		}
    	}
    }
    
    int main()
    {
    	try
    	{
    		boost::asio::io_service io_service;
    		tcp::resolver resolver(io_service);
    		tcp::resolver::query query("www.unix8.net", "http");
    		resolver.async_resolve(query, 
    			boost::bind(&printErr,boost::asio::placeholders::error,
    			boost::asio::placeholders::iterator));
    		io_service.run();
    	}
    	catch (std::exception& e)
    	{
    		std::cerr << e.what() << std::endl;
    	}
    	system("pause");
    	return 0;
    }

    这里通过解析www.unix8.net的http服务,返回IP与端口。这里特别注意就是再bind中的参数。异步中要用boost::asio::placeholders::error与boost::asio::placeholders::iterator。

    namespace
    {
      boost::arg<1>& error
        = boost::asio::placeholders::detail::placeholder<1>::get();
      boost::arg<2>& bytes_transferred
        = boost::asio::placeholders::detail::placeholder<2>::get();
      boost::arg<2>& iterator
        = boost::asio::placeholders::detail::placeholder<2>::get();
      boost::arg<2>& signal_number
        = boost::asio::placeholders::detail::placeholder<2>::get();
    } // namespace

    以上为在异步中,和同步中不同的参数。下面的代码是逆向解析的片段。

		tcp::endpoint endpoint(boost::asio::ip::address::from_string("222.216.160.69"), 80);
		boost::system::error_code e;
		tcp::resolver::iterator iter = resolver.resolve(endpoint, e);
广告位

评论已关闭.