【问题标题】:Why does `struct sockaddr` contain a address family field?为什么`struct sockaddr`包含地址族字段?
【发布时间】:2011-03-11 03:09:35
【问题描述】:

为什么struct sockaddr 包含地址族字段?地址族不是已经通过调用socket() 修复了吗?

【问题讨论】:

  • 我的猜测是内核只是根据 bind 中提供的族路由调用。我想每个系列都对应一个不同的内核模块。

标签: c sockets unix


【解决方案1】:

sockaddr 不仅用于connectbind,还用于更多的地方,包括您对所涉及的地址家族没有一些外部知识的地方——getaddrinfo 就是其中之一。

此外,虽然我不认为以下内容等同于在任何地方进行练习,但我可以看到它已经出现在最初设计这些东西的人的眼中:对 socket() 的调用定义了协议族。 sockaddr 包含地址系列。在实践中,我相信这些总是相同的,但理论上你可以拥有一个能够支持两种不同地址类型的协议。

编辑:该参数还有另一种用途。如果您正在使用数据报 (UDP) 套接字,并且您的套接字处于“已连接”状态并具有默认目标地址,则可以通过调用 connect()sockaddr 并将 sa_family 设置为 @987654331 来 clear out that address @。

【讨论】:

  • 嗯... +1 表示“更多地方”和 PF 与 AF 理论,但 struct sockaddr 至少比 getaddrinfo 早 15 年。
  • larsmans,我已经添加了一个使用参数的地方,并且只要struct sockaddr 存在相关方法,就可以在其中使用。不过,我不知道该特定功能是否已经存在了那么长时间。除了那个地方,我不知道还有什么真正需要这个家庭的地方,而且只要struct sockaddr 一直存在。
【解决方案2】:

如果您查看getaddrinfo 接口,这是在地址(名称或数字地址)的交换表示和sockaddr 结构之间进行转换的唯一现代正确方法,我想您会明白为什么需要它。

话虽如此,整个struct sockaddr 都是一大堆错误设计,尤其是用户空间字节序转换。

为什么需要sa_family 字段的另一个很好的例子是getsocknamegetpeername 接口。如果程序从另一个程序继承了文件描述符,并且还不知道它是什么类型的套接字,它需要能够确定它以便建立新的连接,甚至将地址转换为适合交换的表示。

【讨论】:

  • @R:这对于双栈 IPv4/IPv6 服务器套接字检测是否连接了 IPv4 或 IPv6 客户端也很重要。
【解决方案3】:

如果您查看 4.2BSD 的网络代码,即套接字接口的来源,您会看到 sockaddr 被传递给网络接口驱动程序,但套接字 fd 没有。

【讨论】:

    【解决方案4】:

    sa_family 字段用于说明 sa_data 字段中的地址类型。在许多应用程序中,地址族被假定为 IPV4。但是,许多应用程序也支持 IPV6。

    【讨论】:

    • 但是即使对于 IPv6,地址族也已经在对 socket() 的调用中设置了,不是吗?
    猜你喜欢
    • 2014-06-17
    • 2016-10-07
    • 1970-01-01
    • 2015-06-21
    • 1970-01-01
    • 2011-04-11
    • 2011-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多