【问题标题】:Are sockaddr_in and sockaddr_in6 still using sin_len and sin6_len?sockaddr_in 和 sockaddr_in6 是否还在使用 sin_len 和 sin6_len?
【发布时间】:2016-12-19 04:39:30
【问题描述】:

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

我在任何地方都使用 sockaddr_storage、sockaddr_in 和 sockaddr_in6 之间的联合,并且根据 ss_family 使用正确的成员。套接字库可以根据族推断大小是有道理的,因此长度字段确实是多余的。

如果我注释掉设置长度字段的代码,一切仍然适用于 OSX 和 linux,但这可能只是一种错觉,所以我决定在这里问。 不知何故,该变量是否已弃用?我可以安全地停止使用它,并依靠套接字实现来使用家庭变量吗?

【问题讨论】:

    标签: linux windows macos sockets


    【解决方案1】:

    POSIX 规范不需要 sin_len 字段。

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

    3.2 套接字地址结构

    长度成员 sin_len 是在 4.3BSD-Reno 支持时添加的 为 OSI 协议添加了(图 1.15)。在本次发布之前, 第一个成员是sin_family,历史上是一个未签名的 短的。并非所有供应商都支持套接字地址的长度字段 结构和 POSIX 规范不需要这个成员。

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

    拥有一个长度字段可以简化对可变长度套接字地址结构的处理。

    即使存在长度字段,我们也不需要设置它,也不需要检查它,除非我们正在处理路由套接字(第 18 章)。它在内核中由处理来自各种协议族的套接字地址结构(例如,路由表代码)的例程使用。

    从进程向内核传递套接字地址结构的四个套接字函数bind、connect、sendto和sendmsg,都经过sockargs函数伯克利派生的实现(TCPv2 的第 452 页)。该函数从进程复制套接字地址结构,并将其 sin_len 成员显式设置为作为参数传递给这四个函数的结构的大小。从内核向进程传递套接字地址结构的五个套接字函数accept、recvfrom、recvmsg、getpeername和getsockname,在返回之前都设置了sin_len成员过程。

    不幸的是,通常没有简单的编译时测试来确定一个实现是否为其套接字地址结构定义了一个长度字段...我们将在图 3.4 中看到 IPv6 实现需要定义 SIN6_LEN 如果套接字地址结构有一个长度字段。一些 IPv4 实现基于编译时选项(例如,_SOCKADDR_LEN)向应用程序提供套接字地址结构的长度字段。

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

    【讨论】:

    • 不,就像我说的,我尝试评论该变量的用法,一切都还可以。我只是想知道这是否可以,因为我很幸运,或者可以,因为它仍然应该在不使用该变量的情况下工作。我想这回答了它,然后:)
    猜你喜欢
    • 2013-09-07
    • 2015-12-30
    • 2010-10-28
    • 1970-01-01
    • 2012-07-27
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    相关资源
    最近更新 更多