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



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

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

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

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


感谢

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

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

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

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

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

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

主要区别在于,一个是基于连接的(STREAM),另一个是无连接的

使用SOCK_STREAM,您仍然可以获得所有的连接处理,即listen/accept,并且您可以判断另一侧是否关闭了连接。

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

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

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

  2. 如果速度是一个关注点、工具和衡量标准,那么一切都是平等的。(我想您已经知道,只有流套接字提供内置的可靠有序传输,并且只有数据报套接字可以用于发送到多个接收器)。

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

最新更新