Unix域套接字 VS 命名管道?

169
在查看一个名为Unix命名套接字的东西时,我认为它们是命名管道。我看了一下命名管道,没有看出什么区别。我看到它们的初始化方式不同,但这是我注意到的唯一的事情。两者都使用C写入/读取函数,功能相似。
Unix域套接字和命名管道有什么区别?什么时候选择哪个?默认情况下应该使用哪一个(就像我在C++中默认使用vector而不是deque、list或其他什么,如果我需要的话)?

1
@GregHewgill:不幸的是,那个问题更多地是关于“什么是IPC”,而不是我所问的区别 :/。在发布之前我看到了那个问题,我应该链接并说它相关吗?(对我没有帮助) - user34537
1
@acid:是的,链接相关问题并解释你仍然有哪些问题总是一个好主意。 - Ben Voigt
3
这篇文章总结得很好,解密Unix域套接字:http://www.thomasstover.com/uds.html - Cong Ma
3
失效链接:http://www.techdeviancy.com/uds.html - mcdado
2个回答

149

UNIX域套接字通常比命名管道更加灵活。它们的一些优点如下:

  • 您可以将它们用于多个进程之间的通信(例如,具有潜在多个客户端进程连接的服务器进程);
  • 它们是双向的;
  • 它们支持在进程之间传递内核验证的UID / GID凭据;
  • 它们支持在进程之间传递文件描述符;
  • 它们支持分组和连续分组模式。

要使用这些功能中的许多,您需要使用send() / recv()系统调用系列而不是write() / read()


25
另一方面,应该注意到命名管道的优点在于它们可以通过普通的 open(2) 调用进行“连接”,这使它们更适合在通常只接受文件名参数的程序之间构建临时管道。 - Dolda2000

93

一种不同之处在于命名管道是单向的,因此为了进行双向通信,您需要使用两个。而套接字则是双向的。使用两个变量(即,两个管道而非一个套接字)似乎略微更为复杂。

此外,维基百科文章在以下方面非常清楚:“Unix域套接字可以创建为字节流或数据报序列,而管道仅为字节流。”


事实上,命名管道是双向的,但是半双工的。这意味着通信可以从端点A到端点B,或从端点B到端点A,但永远不能同时进行。


3
嗯,有趣 +1。你是否碰巧知道字节流和数据报之间的区别是什么?也许可以像你为这个问题所做的那样,在一两个句子中举个例子? - user34537
11
在数据报模式的管道或套接字中,数据保持边界,这样一个“写入”调用会产生一个“读取”调用。在流模式中,数据可以连接在一起形成一条长流,所以多个写入操作可以被一次性读取,反之亦然。(根据jtoberon的回答,Windows有数据报管道,而Unix则没有。) - Ben Voigt
2
@xaxxon:你完整地阅读了我的评论吗?括号部分解释了即使Unix没有,Windows也有它们。如果您查看CreateNamedPipe文档,您将看到PIPE_TYPE_MESSAGE标志。 - Ben Voigt
6
“@xaxxon: 管道和Unix域套接字都是本地的,因此只要接收方清空其队列,就能保证不丢失数据。” - Ben Voigt
15
是的,与UDP不同,数据报Unix域套接字保证按顺序递送。 - jtchitty
显示剩余2条评论

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