【发布时间】:2011-03-11 03:09:35
【问题描述】:
为什么struct sockaddr 包含地址族字段?地址族不是已经通过调用socket() 修复了吗?
【问题讨论】:
-
我的猜测是内核只是根据 bind 中提供的族路由调用。我想每个系列都对应一个不同的内核模块。
为什么struct sockaddr 包含地址族字段?地址族不是已经通过调用socket() 修复了吗?
【问题讨论】:
sockaddr 不仅用于connect 和bind,还用于更多的地方,包括您对所涉及的地址家族没有一些外部知识的地方——getaddrinfo 就是其中之一。
此外,虽然我不认为以下内容等同于在任何地方进行练习,但我可以看到它已经出现在最初设计这些东西的人的眼中:对 socket() 的调用定义了协议族。 sockaddr 包含地址系列。在实践中,我相信这些总是相同的,但理论上你可以拥有一个能够支持两种不同地址类型的协议。
编辑:该参数还有另一种用途。如果您正在使用数据报 (UDP) 套接字,并且您的套接字处于“已连接”状态并具有默认目标地址,则可以通过调用 connect() 和 sockaddr 并将 sa_family 设置为 @987654331 来 clear out that address @。
【讨论】:
struct sockaddr 至少比 getaddrinfo 早 15 年。
struct sockaddr 存在相关方法,就可以在其中使用。不过,我不知道该特定功能是否已经存在了那么长时间。除了那个地方,我不知道还有什么真正需要这个家庭的地方,而且只要struct sockaddr 一直存在。
如果您查看getaddrinfo 接口,这是在地址(名称或数字地址)的交换表示和sockaddr 结构之间进行转换的唯一现代正确方法,我想您会明白为什么需要它。
话虽如此,整个struct sockaddr 都是一大堆错误设计,尤其是用户空间字节序转换。
为什么需要sa_family 字段的另一个很好的例子是getsockname 和getpeername 接口。如果程序从另一个程序继承了文件描述符,并且还不知道它是什么类型的套接字,它需要能够确定它以便建立新的连接,甚至将地址转换为适合交换的表示。
【讨论】:
如果您查看 4.2BSD 的网络代码,即套接字接口的来源,您会看到 sockaddr 被传递给网络接口驱动程序,但套接字 fd 没有。
【讨论】:
sa_family 字段用于说明 sa_data 字段中的地址类型。在许多应用程序中,地址族被假定为 IPV4。但是,许多应用程序也支持 IPV6。
【讨论】: