70

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

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

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

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


谢谢

4

4 回答 4

81

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

流套接字允许读取任意数量的字节,但仍保留字节序列。换句话说,发送者可能会向套接字写入 4K 的数据,而接收者可以逐字节地使用该数据。反之亦然——发送方可以将几条小消息写入套接字,接收方可以在一次读取中使用这些消息。流套接字不保留消息边界。

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

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

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

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

于 2012-12-19T14:31:16.930 回答
28

主要区别在于一个是基于连接的(STREAMDGRAM

您仍然可以获得所有连接处理,SOCK_STREAMlisten/accept并且您可以判断连接是否被另一方关闭。

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

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

于 2012-12-19T15:59:41.490 回答
2
  1. 一个可能的区别是消息边界。数据报将作为一个整体交付,数据报是自然的消息边界。使用流套接字,您可以读取 N 个字节,并且套接字将阻塞,直到 N 个字节准备好。但这意味着没有明显的消息边界。

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

于 2012-12-19T14:30:23.040 回答
0

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

于 2012-12-20T05:51:38.550 回答