美文网首页
端口查询baisc_resolver

端口查询baisc_resolver

作者: 长不胖的Garfield | 来源:发表于2017-01-19 16:59 被阅读0次

    什么是端口查询

    在进行网络通信时,需要知道对方的确切地址,即端口endpoint,但是很多情况下只知道要通信的主机名及其服务名,这时就可以使用端口查询得到具体的端口。
    譬如在google.com上提供了一个http服务,那么就需要使用主机名google.com和服务名http来得到与之对应的端口。

    概述

    我们知道,从主机得到具体的IP地址是需要和DNS服务器进行通信的,所以在Boost.Asio中提供了ip::resolver_service来实现端口查询,具体的查询动作封装在basic_resolver中,可以理解为一个有限度的socket,能够使用同步或者异步的方式进行查询,而查询参数则封装为ip::basic_resolver_query

    查询参数ip::basic_resolver_query

    可以指定要查询的主机名、服务名以及查询设定:

    • 主机名
      本地为localhost,远程的一般为域名,譬如google.combaidu.com等,在Windows上可以配置host文件来将域名映射到对应的IP地址
    • 服务名
      有一些服务名和端口是对应关系,可以直接根据服务得到端口,具体的对应关系见Service Name and Transport Protocol Port Number Registry
    • 查询设定
      查询设定以bitmask呈现,有以下几项:
    canonical_name;//Determine the canonical name of the host specified in the query
    passive;// Indicate that returned endpoint is intended for use as a locally bound socket endpoint
    numeric_host;  //地址形式的主机名,不再进行对应查询
    numeric_service; //数值形式的服务名,不再进行对应查询
    v4_mapped;  //如果查询IPv6,在没有查询到IPv6地址时,返回IPv4-mapped的IPv6地址
    all_matching; //如果设定了v4_mapped,则返回所有匹配的IPv4和IPv6地址
    address_configured;//没有loopback地址配置时,只返回对应的IPv4或者IPv6
    

    当构造一个本地查询时,默认查询设定为passive|address_configured,当构造远程主机查询时,默认的查询设定为address_configured

    查询结果及迭代器

    由于端口查询结果可能为多个,所以Boost.Asio进行了封装:

    • 查询结果basic_resolver_entry
      包含了查询出来的端口,以及查询入参:主机名、服务名。
    • 查询结果迭代器basic_resolver_iterator
      可以直接构造,也可以由resolver来生成,用来进行结果的遍历动作

    查询动作baisc_resolver

    可以根据io_service直接构造对应的resolver,提供了以下方法:

    • resolve
      同步查询动作,返回查询结果迭代器
    • async_resolve
      异步查询动作,异步Handler原型为void handler(错误码,结果迭代器)
    • cancel
      取消异步查询动作

    使用示例

    同步查询示例

    void test_tcp_resolver()
    {
        io_service io;
    
        ip::tcp::resolver resolver(io);
        boost::system::error_code ec;
    
        auto endpoint_iter = resolver.resolve({ "google.com","https" }, ec);
        if (!ec)
        {
            while (endpoint_iter != ip::tcp::resolver::iterator())
            {
                std::cout << endpoint_iter->endpoint() << "\n";
                endpoint_iter++;
            }
        }
    }
    

    异步查询示例

    void test_tcp_async_resolver()
    {
        io_service io;
    
        ip::tcp::resolver resolver(io);
        boost::system::error_code ec;
    
        resolver.async_resolve({ "google.com","https" },[](auto ec,auto iter){
            if (!ec)
            {
                std::cout<< iter->endpoint()<<"\n";
                //可以对iter进行修改,使其结束
            }
        });
    
        io.run();
    }
    

    总结

    在已知目标端口的情况下可以直接构造端口,如果只是知道主机名可以使用resolver查询对应端口,这两种操作的结果均可以直接给后续的通信接口使用。

    相关文章

      网友评论

          本文标题:端口查询baisc_resolver

          本文链接:https://www.haomeiwen.com/subject/tbpibttx.html