socket编程中AF_INET和PF_INET有啥区别?

Posted

技术标签:

【中文标题】socket编程中AF_INET和PF_INET有啥区别?【英文标题】:What is the difference between AF_INET and PF_INET in socket programming?socket编程中AF_INET和PF_INET有什么区别? 【发布时间】:2011-10-07 10:42:54 【问题描述】:

socket编程中AF_INET和PF_INET有什么区别?

我对在 socket()bind() 中使用 AF_INET 和 PF_INET 感到困惑。

另外,如何在sin_addr字段中给出IP地址?

【问题讨论】:

随便搜一搜:一个结果是this 我也一直在想这个。它们似乎在不同编码器之间的套接字调用中可以互换使用。 @MattH 它们都与新的 Linux 内核相同。您可以在下面杜克的回答中找到相同的内容。 【参考方案1】:

Beej's famous network programming guide 给出了很好的解释:

在某些文档中,您会看到一个神秘的“PF_INET”的提及。 这是自然界中很少见的怪异灵兽,但我 不妨在这里澄清一下。很久以前,曾经是 认为可能是一个地址族(“AF_INET”中的“AF”代表什么 for) 可能支持它们所引用的多个协议 协议族(“PF_INET”中的“PF”代表什么)。 那没有发生。那好吧。所以正确的做法是在你的 struct sockaddr_in 和 PF_INET 在你对 socket() 的调用中。但 实际上,您可以在任何地方使用 AF_INET。而且,由于 这就是 W. Richard Stevens 在他的书中所做的,这就是我要做的 在这里。

【讨论】:

【参考方案2】:

检查头文件解决问题。 可以检查那里的系统编译器。

对于我的系统,AF_INET == PF_INET

AF == 地址族和 PF == 协议族

协议族,与地址族相同。

【讨论】:

/usr/src/linux-headers-X.X.X-XX-generic/include/linux/socket.h【参考方案3】:

有些情况很重要。

如果您在 Cygwin 中将 AF_INET 传递给 socket(),您的套接字可能会或可能不会随机重置。传递 PF_INET 可确保连接正常工作。

诚然,Cygwin 对于套接字编程来说是一团糟,但它一个真实世界的案例,其中 AF_INET 和 PF_INET 不相同。

【讨论】:

请解释一下。我在 Cygwin 的 socket.h 中找到了 #define PF_INET AF_INET【参考方案4】:

其实AF_和PF_是一回事。***上有一些词可以消除你的困惑

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

【讨论】:

【参考方案5】:

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 指协议中的任何内容,通常是套接字/端口。

【讨论】:

【参考方案6】: 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); 

【讨论】:

感谢@codemac,我用过 addr.sin_addr.s_addr = inet_addr("127.0.0.1");但是 inet_pton() 是什么? 对于手册页,当我输入 man bind(2) 或 man bind() 时,终端给出了意外的标记 '(' 错误,而 man bind 给出了 bash 内置函数中的 bind 解释。如何获取 man bind() 的页面。我的意思是 bind() 函数? @jatt.beas:语法为man <section> <topic>,例如man 2 bind.【参考方案7】:

我在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

【讨论】:

当然 Duke,以前的内核也一样吗,我的意思是 3.0 版之前的内核? 据我所知,在所有版本的内核和 libc 中,PF_* == AF_* 在非 Linux 平台上是这样吗? 我想确定一下,你需要检查包含的头文件:) 在 Ubuntu/Debian 上,我在 /usr/src/linux-headers-<kernel_version>/include/linux/socket.h找到了 AF 定义

以上是关于socket编程中AF_INET和PF_INET有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

c语言中关于socket函数的例子

linux网络编程-socket

AF_INET还是PF_INET?

APUE:网络IPC:套接字

socket 3 草稿.

网络编程基础——常见 API 总结