首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么端口号存储为字符串?

问为什么端口号存储为字符串?
EN

Stack Overflow用户
提问于 2022-07-17 12:20:25
回答 2查看 162关注 0票数 0

的问题是:为什么不能将端口号作为16位无符号ints传递给DNS解析函数,以防止std::string到unsigned short的转换?

背景:

我正在查看联网TS和函数tcp::ip::resolver::resolve的boost.asio实现。该函数以您想要连接的服务的web地址和端口号作为输入,并执行DNS名称解析。此函数的签名为

代码语言:javascript
复制
results_type resolve(string_view host, string_view service, ...);

举个例子

代码语言:javascript
复制
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的转换,用户可以只编写

代码语言:javascript
复制
unsigned short port_number{ 80 };

但是,在网络TS或boost.asio库中没有签名用于

代码语言:javascript
复制
results_type resolve(string_view host, PortType service, ...);

(其中PortType将是一个16位的无符号int)。为什么会这样呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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位整数或文件名或其他什么东西。

票数 1
EN

Stack Overflow用户

发布于 2022-07-17 12:32:55

端口也可以通过名称来引用。如果您在*nix土地上的Windows或/etc/services下看起来像/windows/system32/drivers/etc/services (我认为),您将看到端口80也可以被称为端口http。名称是首选的,因为它们更好地记住,您不需要担心底层端口是什么,并且您可以动态更改端口号,而不必通过编辑services文件来重新构建代码。

这意味着这一行也可以称为:std::string port_number{ "http" };

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73011722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档