为什么`struct sockaddr`包含地址族字段?

5

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


我猜测内核只是根据bind中提供的协议族来路由调用。我想每个协议族可能对应着不同的内核模块。 - Aryabhatta
4个回答

4

sockaddr不仅在connectbind中使用,在一些你没有外部地址族知识的地方也会用到,比如getaddrinfo

此外,虽然我不认为以下内容在任何地方都等同于实践,但我可以看出它曾经是设计这些东西的人的关注点:对socket()的调用定义了协议族。而sockaddr则包含地址族。在实践中,我相信这两者总是相同的,但你理论上可以有一个能够支持两种不同地址类型的协议。

编辑:还有另一种方式可以使用该参数。如果你正在使用数据报(UDP)套接字,并且你有一个处于“已连接”状态并具有默认目标地址的套接字,则可以通过调用connect()并将sockaddrsa_family设置为AF_UNSPEC清空该地址


嗯...对于“更多地方”和PF vs. AF理论加1分,但是struct sockaddrgetaddrinfo早至少15年。 - Fred Foo
larsmans,我已经添加了一个使用该参数的位置,并且相关方法与“struct sockaddr”一样古老。虽然我不知道具体功能是否也存在那么久。除了那个地方,我不知道还有什么其他需要family并且像“struct sockaddr”一样古老的东西。 - Jon Bright

2
如果您看一下getaddrinfo接口,它是在不同的表示地址(名称或数字地址)和sockaddr结构之间进行转换的唯一正确的现代方法,我认为您就会明白为什么需要它。
话虽如此,整个struct sockaddr的设计非常混乱,特别是用户空间的字节序转换。
另一个好例子是sa_family字段的必要性,即getsockname和getpeername接口。如果程序从另一个程序继承文件描述符,并且还不知道套接字类型,则需要能够确定套接字类型,以便建立新连接或甚至将地址转换为适合交换的表示形式。

1
@R:对于双栈IPv4/IPv6服务器套接字来说,检测连接的是IPv4还是IPv6客户端也非常重要。 - Remy Lebeau

1

如果你查看4.2BSD的网络代码,这是套接字接口的起源,你会发现sockaddr被传递给网络接口驱动程序,但套接字fd没有。


0

sa_family字段用于告诉sa_data字段中将包含什么类型的地址。在许多应用程序中,地址族被假定为IPV4。然而,许多应用程序也支持IPV6。


1
但是即使对于IPv6,地址族在调用socket()时已经设置了,不是吗? - mdm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接