在 ASIO C++ 网络库中,您可以通过创建查询对象来解析地址,该对象的构造函数接受(可选的是 ip4 或 ip6)、“主机”参数和“服务”参数。“主机”是您想要解析为 IP 号的站点的名称,“服务”(我猜)是端口号。所以这会执行 DNS 查找/请求,但我的理解是 DNS 查询用于查找名称和 IP 号码之间的关联,我根本不明白端口是如何参与其中的。
asio::ip::tcp::resolver::query query{"www.google.com", "80"};
更让我困惑的是,有一个“查询”构造函数只接受“服务”。评论给出了一点解释:
此构造函数通常用于执行本地服务绑定的名称解析
我不明白,我认为 DNS 查找严格用于(名称 -> IP 号码)映射。如果我解析端口 109 的名称,然后解析端口 400 的相同名称,我是否会得到相同的 IP 号码?
该端口不会对名称查找执行任何操作;它就在那里,因此成功查找的结果是一个随时可用的端点,您可以连接到该端点,因为它已经具有端口号。
此外,系统可能有一个类似 的文件
/etc/services
,它为端口分配名称。解析器很可能(尽管我从未尝试过)使用它,因此您可以只提供https
“服务”而不是 443。不过,我认为依赖它风险太大。tcp::resolver
和之间毫无意义的区别udp::resolver
发挥着相同的作用:它允许解析器返回tcp::endpoint
orudp::endpoint
(即使它们包含完全相同的数据......),并且还有助于“服务”文件查找。未给出端口号。给出的是一个服务名称。如果是数字,它将作为端口返回,否则将被解析,就像主机一样。
顺便说一句,主机也是如此(如果它包含 IP 地址,它将按原样返回)。如果您处于安全敏感设置中,您始终可以考虑传递相关标志以指示主机和/或服务必须有效,而无需进一步解析:请参阅https://www.boost.org/doc/libs/1_85_0/doc /html/boost_asio/reference/ip__resolver_query_base/numeric_service.html
协议族之间存在区别,因此更容易编写协议通用代码。区别主要在于生成的端点知道要使用的正确协议族。