Unix域套接字如何区分多个客户端?


73

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

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

是否有unix域协议格式,例如IP协议格式和TCP / UDP格式?域套接字数据报协议的格式是否发布在某处?每个Unix是否有所不同,或者类似POSIX的标准吗?

感谢您的照明。我找不到任何解释此信息的信息。每个来源都只是简单介绍了如何使用域套接字。


通过Unix域协议进行通讯基本上只是文件I / O。除非您通过套接字传递的数据包含源标识,否则无法分辨哪个进程发送了特定的字符串。
Marc

1
@MarcB应该是一个答案
Jim Garrison

3
可以吗?如果服务器写入数据,则读取的第一个客户端将获取数据,而不管该数据是否打算用于该客户端?这使他们几乎毫无用处。
半透明的疼痛

2
@MarcB您所描述的似乎是可疑的。在449页的第5款Linux Programming 2nd Edition UnleashedKurt Wall, et al,它是这样陈述:...with named pipes you cannot tell one process data from another. Using UNIX Domain sockets, you will get a separate session for each process.
eigenfield

Answers:


105

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

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

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

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

如果不绑定路径,则接收过程将无法获得唯一标识对等方的ID。至少不是在我正在运行的Linux内核上(2.6.18-238.19.1.el5)。


好答案。谢谢@rob
nic

6
在Linux中还有用于AF_UNIX的SOCK_SEQPACKET,它允许像SOCK_STREAM中那样进行连接,但也可以像SOCK_DGRAM中那样保留消息边界。
六。

您的解释中的@ rob-mayoff我知道UNIX套接字上没有“发送队列”,因为数据被直接推送到对等方的接收队列。但是似乎sock.sk_wmem_alloc在发送数据时在发送套接字上增加了,而我希望sock.sk_rmem_alloc在对等套接字上增加。
花花公子

@rob mayoff很好地解释了。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.