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

162

套接字(流)和套接字(数据报)有什么区别?

为什么要使用其中之一?

3个回答

352
很久以前,我读过一个很好的比喻,用来解释这两者之间的差异。不幸的是,我不记得在哪里读到的了,因此无法为这个想法提供作者的署名。但我已经在核心比喻中添加了很多自己的知识。以下是具体内容:
流(socket)就像打电话——一方拨打电话,另一方回应,你们互相问候(TCP中的SYN / ACK),然后交换信息。完成后,告别一下(TCP中的FIN / ACK)。如果一方没有听到告别语,通常会重新接通,因为这是意外事件;通常客户端会重新连接服务器。保证数据不会以与发送顺序不同的顺序到达,并且有合理的保证数据不会受损。
数据报(socket)就像在课堂上传纸条。考虑这样一种情况:您并不直接位于接收者旁边,因此纸条将从一个人传递到另一个人。它可能无法到达目的地,或者在到达时可能已被修改。如果您向同一人传递两张纸条,则它们可能以您不打算的顺序到达,因为纸条通过教室的路径可能不同,某个人可能不如另一个人快速传递纸条等等。
因此,当信息的顺序和完整性很重要时,使用流(socket)。文件传输协议就是一个很好的例子。您不希望下载一些文件,其内容随机混乱且受损!
当次序不如及时交付重要(例如VoIP或游戏协议),当您不想承担流(socket)的更高开销时(这就是为什么DNS主要是数据报协议,以便服务器可以非常快速地响应许多请求),或者当您并不太关心数据是否到达目的地时,您会使用数据报(socket)。

针对VoIP和游戏的案例,这类协议包含自己的数据排序机制。但如果一个数据包损坏或丢失,你不想等待流媒体协议(通常是TCP)发出重新发送请求--你需要快速恢复。TCP可能需要花费几分钟才能恢复,而对于实时协议(如游戏或VoIP),甚至三秒钟都是无法接受的!使用像UDP这样的数据报协议允许软件通过简单地忽略丢失的数据或比TCP更早地重新请求来极快速地恢复。

VoIP是忽略丢失数据的好选择--一方将只听到短暂的间隙声,类似于在与电话信号弱的人通话时发生的情况。游戏协议通常要复杂一些,但所采取的行动通常是要么忽略丢失的数据(如果随后接收的数据优先于丢失的数据),要么重新请求丢失的数据,或者请求完整的状态更新以确保客户端的状态与服务器的同步。


3
非常出色,能够详细包含 SYNACK 的细节。 - LazerSharks
5
这个例子或者一个非常相似的例子来自于《Linux程序设计接口》。2010年版书的第1155页和1159页包含了这些例子。 - Josh
谢谢!解释得非常好。 - slinkin

40

流式套接字:

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

数据报套接字:

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

数据不是以相同的顺序发送的吗(不仅仅是“类似”)?也就是说,在流套接字中构建数据包排序机制是没有意义的。 - Matthew D. Scholefield
流通信中的数据包是以“相似”的顺序发送和接收,意味着数据包本身不能保证按顺序传递到接收主机,但TCP会找出差异,重新排列到达的数据包并请求任何似乎在传输过程中丢失的数据。 - Alejandro Blasco
有道理。也许可以将其作为一个差异删除,然后放在下面(因为如果我理解正确的话,在仅涉及数据包发送顺序时,两种情况下发送/接收数据的顺序可能不同)。 - Matthew D. Scholefield
@Rick 更准确地说,套接字被称为端到端点,因为传输协议负责将消息传递到一个或多个网络端点。 - Alejandro Blasco

2
如果是我认为的网络编程,从sockets开始是一个不错的起点。
socket = ip + port
有三种类型的sockets:
流(TCP,顺序和交付保证,无重复,数据没有长度或字符边界,面向连接,可靠,具有并发性)
数据报(UDP,基于数据包,无连接,数据报大小限制,数据可能会丢失或重复,顺序不保证,不可靠)
原始(直接访问较低层协议IP,ICMP)
我没有看到任何关于传输协议类型的严格规定,因此不应该将可靠性误认为是UDP在两端都活动时是可靠的。
可靠性更多地指交付的可靠性,因为使用TCP作为传输协议进行了序列号检查,而这种检查在UDP中不存在。最好使用网络协议分析器如Wireshark、Tcpdump等来查看您的软件到底在做什么;这对于将理论与实践相结合进行验证或合并非常有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接