2012-03-10 117 views
37

TCP具有元组对(IP Addr/port/type)来告诉另一个客户端。 UDP传递客户端IP和端口。 unix域如何跟踪不同的客户端?Unix域套接字如何区分多个客户端?

换句话说,服务器创建一个绑定到某个路径say/tmp/socket的套接字。 2个或更多客户端连接到/ tmp/socket。底下发生了什么,跟踪客户端1和客户端2的数据?我认为网络堆栈在域套接字中不起作用,所以内核在这里做所有的工作?

是否有像Unix协议格式和TCP/UDP格式的unix域协议格式?域套接字数据报协议的格式是否在某处发布?每个unix都不同或者像POSIX那样标准化它吗?

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

+0

谈论unix域协议基本上只是文件I/O。除非通过套接字传递的数据包含源标识,否则无法确定哪个进程发送了特定的字符串。 – 2012-03-10 05:51:52

+0

@MarcB应该是一个答案 – 2012-03-10 05:59:17

+3

这是真的吗?如果服务器写入数据,则第一个读取的客户端获取数据,而不管该数据是否适用于该客户端?这使他们几乎无用。 – 2012-03-10 06:03:12

回答

62

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

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

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

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

如果你没有绑定路径,那么接收过程不能获得唯一标识对等体的id。至少,不是我正在运行的Linux内核(2.6.18-238.19.1.el5)。

+0

感谢您提供了一个非常好的完整答案。 – 2012-03-11 05:38:33

+0

很好的回答。谢谢@rob – nic 2015-04-09 05:06:57

+0

Linux中也有用于AF_UNIX的SOCK_SEQPACKET,它允许像SOCK_STREAM这样的连接,但也保留了像SOCK_DGRAM中的消息边界。 – 2015-09-07 16:10:58