sockaddr_in 中的 sin_port

Posted

技术标签:

【中文标题】sockaddr_in 中的 sin_port【英文标题】:sin_port in sockaddr_in 【发布时间】:2013-02-07 19:31:41 【问题描述】:

如果我需要获取 IP 的主机名,我应该使用哪个端口? getnameinfo() 从哪里获取主机名?

struct sockaddr_in sa;
sa.sin_family    = AF_INET;
sa.sin_port    = htons(?); // which port ?
inet_pton(AF_INET, "x.x.x.x", &(sa.sin_addr));

char host[NI_MAXHOST];
getnameinfo((struct sockaddr *)&sa, sizeof(sa), host, NI_MAXHOST, NULL, 0, NI_NAMEREQD);

puts(host);

【问题讨论】:

【参考方案1】:

如果您不使用servservlen 参数,则端口号无关紧要。否则,它用于通过端口号查找 服务,例如 "ssh" 用于端口 22,"smtp" 用于端口 25 等(请参阅/etc/services 了解更多信息)。

getnameinfo() 可以从许多地方获取主机名(使用nsswitch.conf,可以为各种名称解析启用各种libnss 模块)。在典型的桌面 linux 发行版上,我希望它首先查看 /etc/hosts,然后根据 /etc/resolv.conf 查询 DNS 服务器。

【讨论】:

【参考方案2】:

来自http://www.kernel.org/doc/man-pages/online/pages/man3/getnameinfo.3.html

sa 参数是一个指向通用套接字地址结构的指针(类型为 sockaddr_in 或 sockaddr_in6) 大小为 salen,用于保存输入 IP 地址和 端口号。参数 host 和 serv 是指向调用者分配的指针 getnameinfo() 的缓冲区(大小分别为 hostlen 和 servlen) 放置包含主机和服务名称的以空字符结尾的字符串 分别。

调用者可以指定不需要主机名(或服务名) 提供 NULL 主机(或 serv)参数或零 hostlen(或 servlen) 争论。但是,主机名或服务名中的至少一个必须是 请求。

因此,如果您只对主机名感兴趣,请不要为服务名称提供缓冲区。

关于它的来源,我将听从其他人的意见,但如果您好奇,代码在 glibc 中。

【讨论】:

以上是关于sockaddr_in 中的 sin_port的主要内容,如果未能解决你的问题,请参考以下文章

sockaddr和sockaddr_in的区别

sockaddr和sockaddr_in详解

为啥我们在调用 bind() 时将 sockaddr_in 转换为 sockaddr?

套接字编程,将 sockaddr_in 转换为 sockaddr。为啥?

sockaddr 和 sockaddr_in 之间的转换

如何从 ip 地址或 sockaddr_in 结构 (C++/WinAPI) 中获取主机名?