linux - sockaddr_in 和 sockaddr_in6 还在使用 sin_len 和 sin6_len 吗?

标签 linux windows macos sockets

所以,标题基本上说明了一切。我一直在将我的 unix 套接字 C 代码移植到 Windows,显然这些结构在 Windows 中没有 sin_len 或 sin6_len。

我在各处使用 sockaddr_storage、sockaddr_in 和 sockaddr_in6 之间的联合,并且只是根据 ss_family 使用正确的成员。套接字库可以根据系列推导出大小是有道理的,因此长度字段确实是多余的。

如果我注释掉设置长度字段的代码,在 OSX 和 Linux 上一切仍然有效,但这可能只是一种错觉,所以我决定在这里问一下。 该变量是否已以某种方式弃用?我可以安全地停止使用它,并依靠套接字实现来使用 family 变量吗?

最佳答案

POSIX 规范不需要 sin_len 字段。

这是来自 Unix Network Programming - Vol 1. The Sockets Networking API, 3rd Edition 的相关信息:

3.2 套接字地址结构

The length member, sin_len, was added with 4.3BSD-Reno, when support for the OSI protocols was added (Figure 1.15). Before this release, the first member was sin_family, which was historically an unsigned short. Not all vendors support a length field for socket address structures and the POSIX specification does not require this member.

Steven 进一步提供了该领域背后的动力:

Having a length field simplifies the handling of variable-length socket address structures.

Even if the length field is present, we need never set it and need never examine it, unless we are dealing with routing sockets (Chapter 18). It is used within the kernel by the routines that deal with socket address structures from various protocol families (e.g, the routing table code).

The four socket functions that pass a socket address structure from the process to the kernel, bind, connect, sendto, and sendmsg, all go through the sockargs function in a Berkeley-derived implementation (p. 452 of TCPv2). This function copies the socket address structure from the process and explicitly sets its sin_len member to the size of the structure that was passed as an argument to these four functions. The five socket functions that pass a socket address structure from the kernel to the process, accept, recvfrom, recvmsg, getpeername, and getsockname, all set the sin_len member before returning to the process.

Unfortunately, there is normally no simple compile-time test to determine whether an implementation defines a length field for its socket address structures...We will see in Figure 3.4 that IPv6 implementations are required to define SIN6_LEN if the socket address structures have a length field. Some IPv4 implementations provide the length field of the socket address structure to the application based on a compile-time option (e.g., _SOCKADDR_LEN).

您需要评估代码中 sin_len 的使用情况。如果它只是将其初始化为0,则可以删除代码。如果您正在从 accept、recvfrom、recvmsg、getpeername 或 getsockname 的结果中读取值,不幸的是,您将需要一些特定于平台的编译开关或切换到使用单独的地址长度变量

关于linux - sockaddr_in 和 sockaddr_in6 还在使用 sin_len 和 sin6_len 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38913326/

相关文章:

multithreading - 线程+多个窗口导致奇怪的错误

cocoa - 为什么我的自动释放对象没有被释放?

linux - 有没有办法让 PostgreSQL 在使用某种语言进行整理时不折叠标点符号和空格?

linux - 错误 : importing one of the Python modules required to run yum

python - 如何比较 2 个 .txt 文件与 python 脚本?

php - Memcached 没有出现在 phpinfo() 中

windows - 如何在 5.1 版本的命令行窗口中查找大文件

linux - 为什么 bash 插入额外的引号

c++ - 我必须在 VS 2008 中使用 "Visual"C++ 吗?

c++ - Qt和chm帮助文件格式