networking编程中的stream和数据报有什么区别?

套接字(stream)与套接字(数据报)有什么区别? 为什么使用一个呢?

很久以前,我读了一个很好的比喻来解释两者的区别。 我不记得我在哪里阅读,所以不幸的是,我不能把这个想法归功于作者,但是我也为核心类比增加了很多我自己的知识。 所以在这里:

一个stream套接字就像一个电话 – 一方放置电话,另一方面答案,你互相问好(TCP中的SYN / ACK),然后你交换信息。 一旦你完成了,你说再见(TCP中的FIN / ACK)。 如果一方没有听到再见,他们通常会打电话给对方,因为这是一个意外事件。 通常客户端将重新连接到服务器。 保证数据不会以不同于您发送的顺序到达,并且有合理的保证数据不会被损坏。

数据报套接字就像在课堂上传递一个音符一样。 考虑一下你并不直接与你通过笔记的人相邻的情况; 该笔记将从人到人。 它可能不会到达目的地,并可能会在到达目的地时进行修改。 如果你把两张纸条交给同一个人,他们可能会按照你不想要的顺序到达,因为这些票据在教室里的路线可能不一样,一个人可能不会像另一个那样快速地传递一个音符,等等。

所以当你有信息的时候使用一个stream套接字并且完好无损是很重要的。 文件传输协议就是一个很好的例子。 你不想下载一些文件,内容随机混乱,损坏!

当你不需要更高的stream量开销(这就是为什么DNS主要是一个数据报协议,这样服务器可以做到这一点时,你的订单不及时交付(比如VoIP或游戏协议)很快就会响应很多请求),或者当数据到达目的地时,不必太在意。

为了扩展VoIP /游戏案例,这些协议包括他们自己的数据sorting机制。 但是,如果一个数据包被损坏或丢失,您不希望等待stream协议(通常是TCP)发出重新发送请求 – 您需要快速恢复。 TCP可能需要几分钟时间才能恢复,而对于实时协议(如游戏或VoIP),即使是三秒钟也是不可接受的! 通过使用像UDP这样的数据报协议,软件可以非常迅速地从这样的事件中恢复,只需简单地忽略丢失的数据或者比TCP更快地重新请求数据。

VoIP是一个很好的候选人,可以简单地忽略丢失的数据 – 一方只会听到一个短小的差距,类似于在接收不好时与手机上的某个人通话时发生的情况。 游戏协议通常稍微复杂一点,但是所采取的行动通常是忽略丢失的数据(如果随后接收到的数据取代丢失的数据),重新请求丢失的数据,或者请求一个完整的状态更新确保客户端的状态与服务器同步。

stream套接字:

  • 服务器和客户端之间专用的点对点通道。
  • 使用TCP协议进行数据传输。
  • 可靠和无损。
  • 以类似的顺序发送/接收数据。
  • 很长时间来恢复丢失/错误的数据

数据报sockets:

  • 服务器和客户端之间没有专用的点对点通道。
  • 使用UDP进行数据传输。
  • 不是100%可靠,可能会丢失数据。
  • 数据发送/接收的顺序可能不一样
  • 不关心或快速恢复丢失/错误的数据