用例解释Unix域套接字 - AF_INET vs AF_UNIX

29

当我在查找 AF_INET 的含义时,我了解到还有另一种称为 UNIX 域套接字 的协议族。这是我阅读的 维基链接

我不理解下面这段话的意思:

UNIX 域套接字使用文件系统作为它们的地址命名空间。它们被进程引用作为文件系统中的索引节点 (inode)。这允许两个进程打开相同的套接字以进行通信。然而,通信完全在操作系统内核中进行。

如果我想使用 SSH 或 FTP ,我应该使用哪个协议族: AF_INET 或 AF_UNIX?我有点困惑。

2个回答

56

如果您想与远程主机通信,那么您可能需要一个 INET 套接字。

不同之处在于,INET 套接字绑定到IP地址-端口元组,而 UNIX 套接字则“绑定”到文件系统上的特殊文件。通常,只有运行在同一台计算机上的进程才能通过后者进行通信。

那么,为什么要使用 UNIX 套接字?正是出于上述原因:在同一主机上的进程间通信,是通过回环的轻量级替代品,相对于 INET 套接字。

事实上,INET 套接字位于完整 TCP/IP 协议栈的顶部,具有处理流量拥塞算法、退避等问题的功能。由于所有内容都被设计为局限于本地计算机,所以 UNIX 套接字不必处理任何这些问题,因此它的代码更简单,通信更快速。当然,在重载下(例如在 Nginx 后面反向代理应用服务器(Node.js、Tornado 等)时),您可能只会在重载下才会注意到差异。


这可能是一个愚蠢的问题:你能举个例子,说明在同一主机上进程之间的通信是如何进行的吗? - eagertoLearn
3
在编程中,进程之间相互交换数据非常普遍,尤其是同一个应用程序的多个实例或一组相关的应用程序协同工作。使用套接字进行这种交换只是可用的众多不同机制中的其中一种,用于进程间通信。 - Remy Lebeau
1
很遗憾,由于涉及进程间通信的架构通常并不简单,因此没有简单的示例可供参考。我能想到的唯一一个是 Chrome Web 浏览器:您可能知道它通过将每个选项卡作为不同的进程运行以及一些其他控制/渲染进程来管理沙盒。尽管如此,您仍然可以将 Chrome 用作单个应用程序,因为这些进程彼此通信。在 Linux 上,这种通信是通过 UNIX 套接字完成的。 - Stefano Sanfilippo
1
另一个例子是当wpa_supplicant作为守护进程运行时。该守护进程需要高权限才能与网络接口通信,但是将所有这些权限都授予每个用户非常危险。因此,用户通过“遥控器”来控制它,这只是一个本地套接字,您可以使用它向守护进程发送命令。 - Stefano Sanfilippo
2
@eagertoLearn - 很高兴你有兴趣了解差异,而不是盲目地编写代码。使用域套接字的应用程序代码的完美示例是X服务器组件。如果你在Linux上使用GNOMEKDE,你会看到在/tmp中会有套接字。ls -la /tmp将显示套接字,或者你甚至可以使用find /tmp -type s。Remy的解释是为什么X服务器组件使用域套接字的原因。 - alvits
@StefanoSanfilippo - 对于一个解释得很好的答案点赞。 - alvits

2
AF_UNIX套接字提供了很好的进程间通信方式。打开一个socket pair socketpair(..)" 并绑定到一个临时文件名。向其中一个写入数据,另一个就能接收到。内核在没有协议或文件系统开销的情况下路由消息。可以使用阻塞I/O或select(...)以FIFO方式同步线程和进程。我喜欢使用非阻塞模式与select和数据报(可以获取长度),但您可以选择自己的模式。请确保在退出时删除临时文件(它将具有零字节,但仍将显示在文件系统目录中)。

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