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

Man*_*ana 55 unix sockets linux udp tcp

这个问题不是 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的套接字?


谢谢

Nik*_*sov 62

就像手册页说Unix套接字总是可靠的一样.SOCK_STREAM和之间的区别在于SOCK_DGRAM从套接字中消耗数据的语义.

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

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

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

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

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

  • 我的意思是,如果你在一个`write()`中发送18个字节,并期望在另一个`read()`中得到18个字节,那对`SOCK_DGRAM`是有效的期望,但对于`SOCK_STREAM`则没有. (6认同)
  • 我认为面向连接和无连接之间的区别比基于流和基于分组的通信之间的差异要重要得多. (4认同)

cme*_*erw 17

主要区别在于一个是基于连接(STREAM)而另一个是无连接(DGRAM) - 流和面向分组的通信之间的差异通常不那么重要.

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

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

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