网络编程中的流和数据报有什么区别?

RoR*_*RoR 125 sockets network-programming datagram

套接字(流)与套接字(数据报)之间有什么区别?为什么用一个而不是另一个?

cdh*_*wie 291

很久以前,我读了一个很好的类比来解释两者之间的区别.我不记得我在哪里阅读它,所以很遗憾我不能相信作者的想法,但我还是将自己的许多知识添加到核心类比中.所以这里:

流套接字就像一个电话呼叫 - 一方拨打电话,另一方接听,你互相打招呼(TCP中的SYN/ACK),然后你交换信息.一旦完成,你就说再见(TCP中的FIN/ACK).如果一方没有听到再见,他们通常会打电话给另一方,因为这是一个意想不到的事件; 通常客户端将重新连接到服务器.可以保证数据不会以与您发送的顺序不同的顺序到达,并且可以合理保证数据不会被损坏.

数据报套接字就像在类中传递注释一样.考虑一下你不是直接在你通过笔记的人旁边的情况; 该笔记将在人与人之间旅行.它可能无法到达目的地,并且可能会在到达目的地时进行修改.如果传递两个音符同一个人,他们可能会到达你不打算命令,因为笔记拿透过教室的路线可能不一样,一个人可能不传纸条一样快,另一个等.

因此,在按顺序获取信息时使用流套接字并且完整性非常重要.文件传输协议就是一个很好的例子.您不想下载某些文件,其内容随机随机播放并损坏!

当你不想要更高的流量开销(这就是为什么DNS主要是数据报协议,因此服务器可以使用时),当订单不如及时交付(想想VoIP或游戏协议)时,你会使用数据报套接字很快就会响应很多很多请求,或者当数据到达目的地时你不太在意.

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

VoIP是一个很好的选择,可以简单地忽略丢失的数据 - 一方只会听到一个短暂的间隙,类似于当他们接收不良时与手机上的某人交谈时发生的情况.游戏的协议,往往是一个稍微复杂一些,但所采取的行动通常是要么忽略丢失的数据(如果随后接收到的数据将取代该丢失的数据),重新请求丢失的数据,或要求一个完整的状态更新确保客户端的状态与服务器的状态同步.

  • 包含 SYNACK 的细节简直太棒了。 (3认同)
  • 这个示例或一个非常相似的示例来自Linux编程接口。2010版在第1155页和第1159页上包含这些示例。 (2认同)

Ale*_*sco 28

流套接字:

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

数据报套接字:

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