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有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章