【问题标题】:How do Unix Domain Sockets differentiate between multiple clients?Unix 域套接字如何区分多个客户端?
【发布时间】:2012-03-27 12:08:08
【问题描述】:

TCP 有元组对(IP 地址/端口/类型)来区分一个客户端和另一个客户端。 UDP 传递客户端 IP 和端口。 unix 域如何跟踪不同的客户端?

换句话说,服务器创建一个绑定到某个路径的套接字,例如 /tmp/socket。 2 个或更多客户端连接到 /tmp/socket。下面发生了什么来跟踪来自 client1 和 client2 的数据?我想网络堆栈在域套接字中没有任何作用,那么内核是否在这里完成所有工作?

是否有像 IP 协议格式和 TCP/UDP 格式一样的 unix 域协议格式?域套接字数据报协议的格式是否在某处发布?每个 unix 都不同吗?还是 POSIX 之类的东西对其进行了标准化?

感谢您的任何启发。我找不到任何解释这一点的信息。每个来源都只是掩饰了如何使用域套接字。

【问题讨论】:

  • 通过 unix 域协议交谈基本上只是文件 i/o。除非您通过套接字传递的数据包含源标识,否则无法判断哪个进程发送了特定的字符串。
  • @MarcB 这应该是一个答案
  • 这是真的吗?如果服务器写入数据,则读取的第一个客户端会获取数据,无论它是否用于该客户端?这使它们几乎毫无用处。
  • @MarcB 您所描述的内容似乎令人怀疑。在Kurt Wall, et alLinux Programming 2nd Edition Unleashed的第449页第5段中,是这样说的:...with named pipes you cannot tell one process data from another. Using UNIX Domain sockets, you will get a separate session for each process.

标签: linux sockets ipc unix-socket


【解决方案1】:

如果创建PF_UNIX 类型为SOCK_STREAM 的套接字,并在其上接受连接,那么每次接受连接时,都会获得一个新的文件描述符(作为accept 系统调用的返回值) .此文件描述符从客户端进程中的文件描述符读取数据并将数据写入数据。因此它就像一个 TCP/IP 连接一样工作。

没有“unix 域协议格式”。不需要,因为 Unix 域套接字无法通过网络连接连接到对等方。在内核中,代表SOCK_STREAM Unix 域套接字结束的文件描述符指向一个数据结构,该结构告诉内核哪个文件描述符位于连接的另一端。当您将数据写入文件描述符时,内核会在连接的另一端查找文件描述符并将数据附加到其他文件描述符的读取缓冲区。内核不需要将您的数据放入带有描述其目的地的标头的数据包中。

对于SOCK_DGRAM 套接字,您必须告诉内核应该接收数据的套接字的路径,它会使用该路径查找该接收套接字的文件描述符。

如果您在连接到服务器套接字之前(或者如果您使用SOCK_DGRAM,则在发送数据之前)将路径绑定到客户端套接字,那么服务器进程可以使用getpeername 获取该路径(对于@ 987654328@)。对于SOCK_DGRAM,接收端可以使用recvfrom获取发送socket的路径。

如果不绑定路径,那么接收进程就无法获得唯一标识对等体的id。至少,不在我正在运行的 Linux 内核上 (2.6.18-238.19.1.el5)。

【讨论】:

  • 很好的答案。谢谢@rob
  • Linux 中还有用于 AF_UNIX 的 SOCK_SEQPACKET,它允许像 SOCK_STREAM 中的连接,但也像 SOCK_DGRAM 中一样保留消息边界。
  • @rob-mayoff 从您的解释中我了解到 UNIX 套接字上没有“发送队列”,因为数据直接推送到对等方的接收队列。但似乎sock.sk_wmem_alloc 在发送数据时在发送套接字上递增,而我希望sock.sk_rmem_alloc 在对等套接字上递增。
  • @rob mayoff 解释得很好。
猜你喜欢
  • 1970-01-01
  • 2012-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-19
  • 1970-01-01
  • 2019-04-02
  • 2016-01-05
相关资源
最近更新 更多