2016-11-22 56 views
2

我有点困惑我应该使用哪种类型的解析器用于我正在开发的一个项目。我在asio文档中找不到答案。我应该使用哪种类型的asio解析器对象?

我知道DNS可以同时用于UDP或TCP,并且通常通过TCP发送较大的响应。

asio同时提供ip :: tcp :: resolver和ip :: udp :: resolver。

  • 我可以交替使用它们吗?
  • 将名称解析为端点后,我计划与 连接一个TCP套接字。这是否意味着我必须使用ip :: tcp :: resolver?

如果有事实互换:

  • 是否有性能优势,使用UDP解析器?
  • 使用TCP解析器还有其他好处吗?
  • 如果我使用UDP解析器,是否需要处理响应对于UDP查找太大并使用TCP重试? (我希望连接到可以解析为每个主机多个IP地址的CDN)

回答

3

使用与套接字具有相同协议的解析器。例如,tcp::socket::connect()预计tcp::endpoint,并且通过udp::resolver::iterator提供的端点类型是udp::endpoint。试图直接使用查询的结果从一个不同的协议将导致编译错误:

boost::asio::io_service io_service; 
boost::asio::ip::tcp::socket socket(io_service); 
boost::asio::ip::udp::resolver::iterator iterator = ...; 
socket.connect(iterator->endpoint()); 
// ~~~^~~~~~~ no matching function call to `tcp::socket::connect(udp::endpoint)` 
//   no known conversion from `udp::endpoint` to `tcp::endpoint` 

既不tcp::resolver也不udp::resolver口授传输层协议名称解析将使用。当DNS客户端成为必要时,或者它已被明确配置为使用TCP时,DNS客户端将使用TCP。

在支持服务名称解析的系统上,使用描述性服务名称执行服务名称解析时,解析器的类型会影响结果。例如,在IANA Service Name and Transport Protocol Port Number Registry

  • daytime服务使用端口13上的UDP和TCP
  • shell服务使用端口514仅在TCP
  • syslog服务仅在UDP
使用端口514

因此,可以使用tcp::resolver来解析daytimeshell服务,但不能解析syslog。另一方面,udp::resolver可以解析daytimesyslog,但不能解析shell。以下示例演示了这种区别:

#include <boost/asio.hpp> 

int main() 
{ 
    boost::asio::io_service io_service; 

    using tcp = boost::asio::ip::tcp; 
    using udp = boost::asio::ip::udp; 

    boost::system::error_code error; 
    tcp::resolver tcp_resolver(io_service); 
    udp::resolver udp_resolver(io_service); 

    // daytime is 13/tcp and 13/udp 
    tcp_resolver.resolve(tcp::resolver::query("daytime"), error); 
    assert(!error); 
    udp_resolver.resolve(udp::resolver::query("daytime"), error); 
    assert(!error); 

    // shell is 514/tcp 
    tcp_resolver.resolve(tcp::resolver::query("shell"), error); 
    assert(!error); 
    udp_resolver.resolve(udp::resolver::query("shell"), error); 
    assert(error); 

    // syslog is 514/udp 
    tcp_resolver.resolve(tcp::resolver::query("syslog"), error); 
    assert(error); 
    udp_resolver.resolve(udp::resolver::query("syslog"), error); 
    assert(!error); 

    tcp_resolver.resolve(tcp::resolver::query("514"), error); 
    assert(!error); 
    udp_resolver.resolve(udp::resolver::query("514"), error); 
    assert(!error); 
} 
相关问题