Linux UNIX 域 STREAM 和 DATAGRAM 套接字之间的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13953912/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 18:04:51  来源:igfitidea点击:

Difference between UNIX domain STREAM and DATAGRAM sockets?

linuxsocketsunixtcpudp

提问by Manik Sidana

This question is NOTfor the difference between STREAM type and DATAGRAM type INTERNET sockets. I know that STREAM sockets use TCP, Datagram sockets use UDP and all the TCP,UDP stuff, packets arriving in order, ACK, NACK etc. I understand the importance of these over internet.

这个问题不是针对 STREAM 类型和 DATAGRAM 类型 INTERNET 套接字之间的区别。我知道 STREAM 套接字使用 TCP,数据报套接字使用 UDP 以及所有 TCP、UDP 内容、按顺序到达的数据包、ACK、NACK 等。我了解这些在 Internet 上的重要性。

Q1) When I create a UNIX domain socket which is a local socket, how would it matter if the socket is STREAM socket or DATAGRAM socket. This type of socket would write the data to the socket file, would the protocol matter in this case since I am not transmitting data over a network? Is there any chance of data loss in this case if I use UNIX-based DATAGRAM sockets?

Q2) Does UNIX DATAGRAM sockets provide better performance than UNIX STREAM sockets?

Q3) How to decide for a STREAM/DATAGRAM UNIX based socket in my application?

Q1)当我创建一个本地套接字的 UNIX 域套接字时,该套接字是 STREAM 套接字还是 DATAGRAM 套接字有什么关系。这种类型的套接字会将数据写入套接字文件,在这种情况下协议是否重要,因为我没有通过网络传输数据?如果我使用基于 UNIX 的 DATAGRAM 套接字,在这种情况下是否有数据丢失的可能性?

Q2) UNIX DATAGRAM 套接字是否比 UNIX STREAM 套接字提供更好的性能?

Q3) 如何决定在我的应用程序中使用基于 STREAM/DATAGRAM UNIX 的套接字?


Thanks


谢谢

采纳答案by Nikolai Fetissov

Just as the manual pagesays Unix sockets are always reliable. The difference between SOCK_STREAMand SOCK_DGRAMis in the semantics of consuming data out of the socket.

正如手册页所说的 Unix 套接字总是可靠的。SOCK_STREAM和之间的区别在于SOCK_DGRAM从套接字消费数据的语义。

Stream socket allows for reading arbitrary number of bytes, but still preserving byte sequence. In other words, a sender might write 4K of data to the socket, and the receiver can consume that data byte by byte. The other way around is true too - sender can write several small messages to the socket that the receiver can consume in one read. Stream socket does not preserve message boundaries.

流套接字允许读取任意数量的字节,但仍保留字节序列。换句话说,发送方可能将 4K 的数据写入套接字,而接收方可以逐字节使用该数据。另一种方式也是如此 - 发送方可以将几条小消息写入接收方可以在一次读取中使用的套接字。流套接字不保留消息边界。

Datagram socket, on the other hand, does preserve these boundaries - one write by the sender always corresponds to one read by the receiver (even if receiver's buffer given to read(2)or recv(2)is smaller then that message).

另一方面,数据报套接字确实保留了这些边界——发送者的一次写入总是对应于接收者的一次读取(即使接收者的缓冲区给予该消息read(2)recv(2)小于该消息)。

So if your application protocol has small messages with known upper bound on message size you are better off with SOCK_DGRAMsince that's easier to manage.

因此,如果您的应用程序协议具有已知消息大小上限的小消息,那么您最好使用SOCK_DGRAM它,因为这样更易于管理。

If your protocol calls for arbitrary long message payloads, or is just an unstructured stream (like raw audio or something), then pick SOCK_STREAMand do the required buffering.

如果您的协议要求任意长消息有效负载,或者只是一个非结构化的流(如原始音频或其他内容),则选择SOCK_STREAM并执行所需的缓冲。

Performance should be the same since both types just go through local in-kernel memory, just the buffer management is different.

性能应该相同,因为这两种类型都只通过本地内核内存,只是缓冲区管理不同。

回答by Jens

  1. One likely difference are message boundaries. Datagrams will be delivered as a whole with the datagrams being the natural message boundaries. With stream sockets you can read N bytes and the socket will block until N bytes are ready. But this means no obvious message boundaries.

  2. All things being equal, if speed is a concern, instrument and measure. (I assume you already know that only a stream socket provides built-in reliable in-order transport, and only datagram sockets can be used to send to multiplereceivers).

  1. 一个可能的区别是消息边界。数据报将作为一个整体交付,数据报是自然的消息边界。使用流套接字,您可以读取 N 个字节,并且套接字将阻塞,直到 N 个字节准备就绪。但这意味着没有明显的消息边界。

  2. 一切都是平等的,如果速度是一个问题,工具和措施。(我假设您已经知道只有流套接字提供内置可靠的有序传输,并且只有数据报套接字可用于发送到多个接收器)。

回答by cmeerw

The main difference is that one is connection based(STREAM) and the other is connection-less(DGRAM) - the difference between stream and packet oriented communication is usually much less important.

主要区别在于一种是基于连接的( STREAM) 和另一种是无连接的( DGRAM) - 面向流和面向数据包的通信之间的区别通常不那么重要。

With SOCK_STREAMyou still get all the connection handling, i.e. listen/acceptand you can tell if a connection is closed by the other side.

有了SOCK_STREAM你仍然可以得到所有的连接处理,即listen/accept你能告诉如果连接被对方关闭。

Note that there is also a SEQPACKETsocket type that's still connection oriented, but preserves message boundaries (which might save you from implementing a message-oriented layer on top of a STREAMsocket).

请注意,还有一种SEQPACKET套接字类型仍然是面向连接的,但保留了消息边界(这可能会使您免于在STREAM套接字之上实现面向消息的层)。

I would expect data transfer performance to be similar for all of these types, the main difference is just what semantics you want.

我希望所有这些类型的数据传输性能都相似,主要区别在于您想要的语义。

回答by Arun Taylor

If the clients and servers will always be on the same machine and the goal is to have minimal latency and maximum bandwidth, use shared memory.

如果客户端和服务器总是在同一台机器上,并且目标是最小延迟和最大带宽,请使用共享内存。