我应该使用什么类型的 asio 解析器对象?
What type of asio resolver object should I use?
对于我正在从事的副项目应该使用哪种类型的解析器,我有点困惑。我没有在 asio 文档中找到答案。
我知道 DNS 可以与 UDP 或 TCP 一起工作,并且较大的响应通常通过 TCP 发送。
asio 同时提供 ip::tcp::resolver 和 ip::udp::resolver。
- 我可以互换使用它们吗?
- 将名称解析为端点后,我打算连接
一个 TCP 套接字。这是否意味着我必须使用 ip::tcp::resolver?
如果有其实可以互换的:
- 使用 UDP 解析器对性能有好处吗?
- 使用 TCP 解析器还有其他好处吗?
- 如果我使用 UDP 解析器,我是否需要处理对于 UDP 查找而言太大的响应并使用 TCP 重试? (我希望连接到一个 CDN,它将为每个主机解析多个 IP 地址)
使用与套接字具有相同协议的解析器。例如,tcp::socket::connect()
expects a tcp::endpoint
, and the endpoint type provided via udp::resolver::iterator
is 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
nor udp::resolver
均未指定名称解析将使用的传输层协议。 DNS 客户端将在必要时或已明确配置为使用 TCP 时使用 TCP。
在支持服务名称解析的系统上,当使用描述性服务名称执行服务名称解析时,解析器的类型会影响结果。例如,在 IANA Service Name and Transport Protocol Port Number Registry:
daytime
服务在 UDP 和 TCP 上使用端口 13
shell
服务仅在 TCP 上使用端口 514
syslog
服务仅在 UDP 上使用端口 514
因此,可以使用 tcp::resolver
来解析 daytime
和 shell
服务,但不能使用 syslog
。另一方面,udp::resolver
可以解析 daytime
和 syslog
,但不能解析 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);
}
对于我正在从事的副项目应该使用哪种类型的解析器,我有点困惑。我没有在 asio 文档中找到答案。
我知道 DNS 可以与 UDP 或 TCP 一起工作,并且较大的响应通常通过 TCP 发送。
asio 同时提供 ip::tcp::resolver 和 ip::udp::resolver。
- 我可以互换使用它们吗?
- 将名称解析为端点后,我打算连接 一个 TCP 套接字。这是否意味着我必须使用 ip::tcp::resolver?
如果有其实可以互换的:
- 使用 UDP 解析器对性能有好处吗?
- 使用 TCP 解析器还有其他好处吗?
- 如果我使用 UDP 解析器,我是否需要处理对于 UDP 查找而言太大的响应并使用 TCP 重试? (我希望连接到一个 CDN,它将为每个主机解析多个 IP 地址)
使用与套接字具有相同协议的解析器。例如,tcp::socket::connect()
expects a tcp::endpoint
, and the endpoint type provided via udp::resolver::iterator
is 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
nor udp::resolver
均未指定名称解析将使用的传输层协议。 DNS 客户端将在必要时或已明确配置为使用 TCP 时使用 TCP。
在支持服务名称解析的系统上,当使用描述性服务名称执行服务名称解析时,解析器的类型会影响结果。例如,在 IANA Service Name and Transport Protocol Port Number Registry:
daytime
服务在 UDP 和 TCP 上使用端口 13shell
服务仅在 TCP 上使用端口 514
syslog
服务仅在 UDP 上使用端口 514
因此,可以使用 tcp::resolver
来解析 daytime
和 shell
服务,但不能使用 syslog
。另一方面,udp::resolver
可以解析 daytime
和 syslog
,但不能解析 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);
}