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

时间:2011-01-14 07:31:39

标签: sockets network-programming datagram

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

3 个答案:

答案 0 :(得分:282)

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

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

数据报套接字就像在课堂上传递一个音符一样。考虑一下你不是直接在你通过笔记的人旁边的情况;该笔记将在人与人之间旅行。它可能无法到达目的地,并且可能会在到达目的地时进行修改。如果您将两个笔记传递给同一个人,他们可能会按照您不想要的顺序到达,因为笔记通过教室的路线可能不一样,一个人可能不会像另一个那样快速传递笔记,等等

因此,在按顺序获取信息时,您使用流套接字并且完整无缺。文件传输协议就是一个很好的例子。你不想下载一些文件,其中的内容随机乱丢并损坏!

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

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

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

答案 1 :(得分:25)

Stream Socket:

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

数据报套接字:

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

答案 2 :(得分:0)

如果是网络编程,我认为从套接字开始是一个很好的开始。
套接字= IP +端口
插座有三种类型
流(TCP,顺序和交付得到保证,没有重复,没有数据的长度或字符边界,面向连接,可靠,并发)
数据报(UDP,基于数据包,无连接,数据报大小限制,数据可能丢失或重复,无法保证顺序,不可靠)
原始(直接访问下层协议IP,ICMP)
对于哪个套接字必须使用哪种传输协议,对于传输协议类型,我没有看到任何严格的规则,并且不应误解可靠性,因为在两端都处于活动状态的情况下,UDP是可以实现的。
可靠性更像是传递的可靠性,这是因为使用TCP作为传输协议进行了序列号检查,而UDP中不存在这种序列号检查。最好使用wireshark tcpdump等网络协议分析器来查看软件的功能。验证或将理论与实际工作结合到纸上。