这个问题是关于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_STREAM
和SOCK_DGRAM
之间的区别在于从套接字中消费数据的语义。
流套接字允许读取任意数量的字节,但仍保留字节序列。换句话说,发送方可能会向套接字写入4K的数据,接收方可以逐字节消耗该数据。另一种方式也是如此——发送方可以向套接字写入几个小消息,接收方可以在一次读取中使用这些消息。流套接字不保留消息边界。
另一方面,数据报套接字确实保留了这些边界——发送方的一次写入总是与接收方的一次读取相对应(即使接收方给read(2)
或recv(2)
的缓冲区小于该消息)。
因此,如果您的应用程序协议具有已知消息大小上限的小消息,则最好使用SOCK_DGRAM
,因为它更易于管理。
如果您的协议需要任意的长消息有效载荷,或者只是一个非结构化流(如原始音频或其他内容),那么选择SOCK_STREAM
并进行所需的缓冲。
性能应该是相同的,因为这两种类型只是通过内核内存中的本地,只是缓冲区管理不同。
主要区别在于,一个是基于连接的(STREAM
),另一个是无连接的
使用SOCK_STREAM
,您仍然可以获得所有的连接处理,即listen
/accept
,并且您可以判断另一侧是否关闭了连接。
请注意,还有一个SEQPACKET
套接字类型仍然是面向连接的,但保留了消息边界(这可能会使您免于在STREAM
套接字之上实现面向消息的层)。
我希望所有这些类型的数据传输性能都相似,主要区别在于您想要什么语义。
-
一个可能的区别是消息边界。数据报将作为一个整体交付,数据报是自然的消息边界。使用流套接字,您可以读取N个字节,套接字将阻塞,直到N个字节就绪。但这意味着没有明显的信息边界。
-
如果速度是一个关注点、工具和衡量标准,那么一切都是平等的。(我想您已经知道,只有流套接字提供内置的可靠有序传输,并且只有数据报套接字可以用于发送到多个接收器)。
如果客户端和服务器总是在同一台机器上,并且目标是具有最小延迟和最大带宽,则使用共享内存。