Linux Unix 域套接字如何区分多个客户端?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9644251/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do Unix Domain Sockets differentiate between multiple clients?
提问by Translucent Pain
TCP has the tuple pairs (IP Addr/port/type) to tell one client from another. UDP passes the client IP and port. How does the unix domain keep track of different clients?
TCP 有元组对(IP 地址/端口/类型)来告诉一个客户端和另一个客户端。UDP 传递客户端 IP 和端口。unix 域如何跟踪不同的客户端?
In other words the server creates a socket bound to some path say /tmp/socket. 2 or more clients connect to /tmp/socket. What is going on underneath that keeps track of data from client1 and client2? I imagine the network stack plays no part in domain sockets so is the kernel doing all the work here?
换句话说,服务器创建一个绑定到某个路径的套接字,比如 /tmp/socket。2 个或更多客户端连接到 /tmp/socket。下面发生了什么来跟踪来自客户端 1 和客户端 2 的数据?我想网络堆栈在域套接字中不起作用,所以内核在这里完成所有工作吗?
Is there a unix domain protocol format like there is an IP protocol format and TCP/UDP formats? Is the format of domain socket datagram protocols published somewhere? Is every unix different or does something like POSIX standardize it?
是否有像 IP 协议格式和 TCP/UDP 格式一样的 unix 域协议格式?域套接字数据报协议的格式是否在某处发布?每个unix都不同还是像POSIX之类的东西对其进行了标准化?
Thanks for any illumination. I could not find any information that explained this. Every source just glossed over how to use the domain sockets.
感谢您的任何照明。我找不到任何解释这一点的信息。每个消息来源只是掩盖了如何使用域套接字。
采纳答案by rob mayoff
If you create a PF_UNIX
socket of type SOCK_STREAM
, and accept connections on it, then each time you accept a connection, you get a new file descriptor (as the return value of the accept
system call). This file descriptor reads data from and writes data to a file descriptor in the client process. Thus it works just like a TCP/IP connection.
如果您创建一个PF_UNIX
类型为 的套接字SOCK_STREAM
,并在其上接受连接,那么每次接受连接时,您都会获得一个新的文件描述符(作为accept
系统调用的返回值)。此文件描述符从客户端进程中的文件描述符读取数据并将数据写入其中。因此它就像一个 TCP/IP 连接一样工作。
There's no “unix domain protocol format”. There doesn't need to be, because a Unix-domain socket can't be connected to a peer over a network connection. In the kernel, the file descriptor representing your end of a SOCK_STREAM
Unix-domain socket points to a data structure that tells the kernel which file descriptor is at the other end of the connection. When you write data to your file descriptor, the kernel looks up the file descriptor at the other end of the connection and appends the data to that other file descriptor's read buffer. The kernel doesn't need to put your data inside a packet with a header describing its destination.
没有“unix 域协议格式”。没有必要,因为 Unix 域套接字无法通过网络连接连接到对等方。在内核中,代表您的SOCK_STREAM
Unix 域套接字端的文件描述符指向一个数据结构,该数据结构告诉内核哪个文件描述符位于连接的另一端。当您将数据写入文件描述符时,内核会在连接的另一端查找文件描述符,并将数据附加到另一个文件描述符的读取缓冲区。内核不需要将您的数据放入带有描述其目的地的标头的数据包中。
For a SOCK_DGRAM
socket, you have to tell the kernel the path of the socket that should receive your data, and it uses that to look up the file descriptor for that receiving socket.
对于SOCK_DGRAM
套接字,您必须告诉内核应该接收数据的套接字的路径,它使用它来查找该接收套接字的文件描述符。
If you bind a path to your client socket before you connect to the server socket (or before you send data if you're using SOCK_DGRAM
), then the server process can get that path using getpeername
(for SOCK_STREAM
). For a SOCK_DGRAM
, the receiving side can use recvfrom
to get the path of the sending socket.
如果在连接到服务器套接字之前(或者在使用 发送数据之前)将路径绑定到客户端套接字SOCK_DGRAM
,则服务器进程可以使用getpeername
(for SOCK_STREAM
)获取该路径。对于 a SOCK_DGRAM
,接收方可以使用recvfrom
来获取发送套接字的路径。
If you don't bind a path, then the receiving process can't get an id that uniquely identifies the peer. At least, not on the Linux kernel I'm running (2.6.18-238.19.1.el5
).
如果不绑定路径,那么接收进程就无法得到唯一标识对等方的id。至少,不是在我运行的 Linux 内核上 ( 2.6.18-238.19.1.el5
)。