的问题是:为什么不能将端口号作为16位无符号ints传递给DNS解析函数,以防止std::string到unsigned short的转换?
背景:
我正在查看联网TS和函数tcp::ip::resolver::resolve的boost.asio实现。该函数以您想要连接的服务的web地址和端口号作为输入,并执行DNS名称解析。此函数的签名为
results_type resolve(string_view host, string_view service, ...);举个例子
boost::asio::io_context serv{};
boost::asio::ip::tcp::resolver res{serv};
std::string web_address{ "www.google.com" };
std::string port_number{ "80" };
auto result = res.resolve(web_address, port_number);为www.google.com执行DNS查找。最终,在TCP报头中,端口号需要存储为16位无符号int。如果用户希望保存std::string到unsigned short的转换,用户可以只编写
unsigned short port_number{ 80 };但是,在网络TS或boost.asio库中没有签名用于
results_type resolve(string_view host, PortType service, ...);(其中PortType将是一个16位的无符号int)。为什么会这样呢?
发布于 2022-07-17 18:39:08
因为它是POSIX getaddrinfo(3)的一个薄包装器,它需要一个const char* service。
由于必须创建字符串才能传递给getadddrinfo(),因此使用uint16_t端口号的额外重载实际上并没有多大好处。使用resolve(web_address, std::to_string(integer_port_number));很好,字符串construction+formatting的开销比进行DNS查找所需的时间要小得多。
绝对有可能有过载需要一个uint16_t端口。它可以对堆栈上的某些内部缓冲区执行字符串格式设置。由于短字符串优化,节省的费用很小,但至少API用户不必转换整数。
对于Boost.Asio开发人员和网络TS人员来说,这似乎是一件值得推荐的事情。它在其他网络API中有先例,它的getaddrinfo将端口作为数字或数字字符串,根据需要进行转换。
另外,端口不是由internet协议( OSI模型中的第3层)指定的,而是由UDP和TCP单独指定的(在传输层,第4层),这意味着它是IP堆栈上任何内容的通用解析器。您可以想象一些不同的传输层,其中端口不是16位整数,而是32位整数或文件名或其他什么东西。
发布于 2022-07-17 12:32:55
端口也可以通过名称来引用。如果您在*nix土地上的Windows或/etc/services下看起来像/windows/system32/drivers/etc/services (我认为),您将看到端口80也可以被称为端口http。名称是首选的,因为它们更好地记住,您不需要担心底层端口是什么,并且您可以动态更改端口号,而不必通过编辑services文件来重新构建代码。
这意味着这一行也可以称为:std::string port_number{ "http" };
https://stackoverflow.com/questions/73011722
复制相似问题