Beej's famous network programming guide 给出了一个很好的解释:
在某些文档中,您会看到提到神秘的“PF_INET”。这是自然界中很少见的一种诡异的虚灵兽,不过在这里我还是稍微澄清一下吧。很久以前,人们认为也许一个地址族(“AF_INET”中的“AF”代表什么)可能支持其协议族引用的多个协议(“PF_INET”中的“PF”代表什么) )。那没有发生。那好吧。所以正确的做法是在你的 struct sockaddr_in 中使用 AF_INET,在你对 socket() 的调用中使用 PF_INET。但实际上,您可以在任何地方使用 AF_INET。而且,因为这就是 W. Richard Stevens 在他的书中所做的,这就是我将在这里做的。
我在 Linux 内核源代码中发现 PF_INET 和 AF_INET 是相同的。以下代码来自文件 include/linux/socket.h,Linux 内核 3.2.21 树的第 204 行。
/* Protocol families, same as address families. */
...
#define PF_INET AF_INET
AF = 地址族
PF = 协议族
意思是,AF_INET
是指来自互联网的地址,特别是 IP 地址。 PF_INET
指协议中的任何内容,通常是套接字/端口。
考虑阅读 socket(2) 和 bind(2) 的手册页。对于 sin_addr
字段,只需执行以下操作即可对其进行设置:
struct sockaddr_in addr;
inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr);
man <section> <topic>
,例如 man 2 bind
。
其实AF_和PF_是一回事。维基百科上有一些词会消除你的困惑
套接字接口的原始设计概念区分了协议类型(族)和每个可能使用的特定地址类型。设想一个协议族可能有几种地址类型。地址类型由附加的符号常量定义,使用前缀 AF_ 而不是 PF_。 AF_ 标识符适用于专门处理地址类型而不是协议族的所有数据结构。然而,这种协议和地址类型分离的概念还没有找到实现支持,AF_-constants 只是由相应的协议标识符定义,使得 AF_ 和 PF_ 常量之间的区别成为没有重大实际意义的技术争论。事实上,这两种形式的正确使用都存在很多混淆。
AF_INET = 地址格式,Internet = IP 地址
PF_INET = 数据包格式,Internet = IP、TCP/IP 或 UDP/IP
AF_INET 是用于您正在创建的套接字的地址族(在本例中为 Internet 协议地址)。例如,Linux 内核支持 29 个其他地址系列,例如 UNIX 套接字和 IPX,还支持与 IRDA 和蓝牙的通信(AF_IRDA 和 AF_BLUETOOTH,但您会怀疑是否会在如此低的级别上使用它们)。
在大多数情况下,坚持使用 AF_INET 进行网络套接字编程是最安全的选择。
意思是,AF_INET 是指来自互联网的地址,特别是 IP 地址。
PF_INET 指的是协议中的任何内容,通常是套接字/端口。
检查头文件解决的问题。可以检查那里的系统编译器。
对于我的系统,AF_INET == PF_INET
AF == 地址族和 PF == 协议族
协议族,与地址族相同。
https://i.stack.imgur.com/iIjqq.png
/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h
有些情况很重要。
如果您在 Cygwin 中将 AF_INET 传递给 socket()
,您的套接字可能会或可能不会被随机重置。传递 PF_INET 可确保连接正常工作。
诚然,Cygwin 对于套接字编程来说是一个巨大的混乱,但它是 AF_INET 和 PF_INET 不相同的真实世界案例。
socket.h
中找到 #define PF_INET AF_INET
。
/usr/src/linux-headers-<kernel_version>/include/linux/socket.h
中找到了 AF 定义