AF_INET和PF_INET常量有什么区别?

35
看一些关于套接字编程的例子,我们可以看到有些人使用AF_INET,而其他人使用PF_INET。此外,有时两者都在同一个示例中使用。问题是:它们之间有什么区别?我们应该使用哪一个?
如果你能回答这个问题,另一个问题是...为什么会有这两个相似(但相等)的常量?

到目前为止我所发现的:

socket手册页面

在(Unix)套接字编程中,我们有socket()函数,它接收以下参数:

int socket(int domain, int type, int protocol);

手册上写道:

domain 参数指定通信域;这选择将用于通信的协议族。这些族在 <sys/socket.h> 中定义。

手册还引用了 AF_INET 以及其他一些 AF_ 常量作为 domain 参数。此外,在同一手册的 NOTES 部分,我们可以读到:

在 4.x BSD 下用于协议族的宏常数是 PF_UNIX、PF_INET 等等,而用于地址族的则是 AF_UNIX 等等。然而,BSD 手册已经承诺:“协议族通常与地址族相同”,随后的标准在各处都使用 AF_*。

C 标头文件

sys/socket.h 实际上并没有定义这些常量,而是包含了 bits/socket.h。该文件定义了约 38 个 AF_ 常量和 38 个类似以下的 PF_ 常量:

#define PF_INET     2   /* IP protocol family.  */
#define AF_INET     PF_INET

Python

Python socket模块与C API非常相似。然而,有许多AF_常量,但只有一个PF_常量(PF_PACKET)。因此,在Python中,我们别无选择,只能使用AF_INET

我认为这个决定只包含AF_常量是遵循了一个指导原则:“应该有一种——最好只有一种——明显的方法来做到这一点。” (Python之禅)

其他信息

这篇论坛帖子链接到这条旧消息,其中包含一些历史信息。


1
请参考此重复问题:https://dev59.com/sGw15IYBdhLWcg3wQ5di - Adam Rosenfield
1个回答

28

我认为维基百科有关此事的注释已经很好地总结了:

套接字接口的最初设计概念区分了协议类型(族)和每个协议类型可以使用的特定地址类型。设想一个协议族可能有几种地址类型。地址类型由附加符号常量定义,使用前缀 AF_ 而不是 PF_AF_ 标识符用于所有专门处理地址类型而不是协议族的数据结构。然而,这种协议和地址类型的分离概念没有找到实现支持,AF_ 常量仅由相应的协议标识符定义,使得 AF_PF_ 常量之间的区别成为一个没有重大实际意义的技术论点。实际上,在正确使用两种形式方面存在很多混淆。

即使今天有人提出了区别的理由,他们也必须想出新的标识符,否则很多东西都会崩溃...


3
简而言之,这是由凡人设计的缺陷。我们必须与之共存。 - smwikipedia

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