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

标签 sockets network-programming datagram

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

为什么要使用其中一种而不是另一种?

最佳答案

很久以前,我读过一个很好的类比来解释两者之间的区别。我不记得我在哪里读到的,所以不幸的是我不能相信作者的想法,但无论如何我也在核心类比中添加了很多我自己的知识。所以这里是:

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

数据报套接字就像在类里面传递笔记一样。考虑一下这样的情况:您并不直接在您要传递纸条的人旁边;这张纸条会从一个人传到另一个人。它可能无法到达目的地,并且在到达目的地时可能会被修改。如果您将两张纸条传递给同一个人,它们可能会以您不希望的顺序到达,因为纸条穿过教室的路线可能不同,一个人传递纸条的速度可能不如另一个人,等等.

因此,当信息有序且完整很重要时,您可以使用流套接字。文件传输协议(protocol)就是一个很好的例子。您不想下载一些内容随机打乱并损坏的文件!

当顺序不如及时交付重要时(例如 VoIP 或游戏协议(protocol)),当您不希望流的更高开销时(这就是 DNS 主要是数据报协议(protocol)的原因,所以,您可以使用数据报套接字)服务器可以非常快速地立即响应许多请求),或者当您不太关心数据是否到达目的地时。

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

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

关于sockets - 网络编程中流和数据报有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4688855/

相关文章:

java - 从Android手机发送数据到java服务器

c - 如何在 Linux 中使用 gethostbyname_r

c# - 如何使用 WOL(局域网唤醒)C# 或 Java 打开联网计算机

Python 套接字模块 : http proxy

C++ - 套接字服务器线程

sockets - Modbus TCP/IP 设备通信问题

c# - 将零字节写入网络流是检测关闭连接的可靠方法吗?

java - DTLS 与使用 JKS/JCE 加密 UDP 数据报的比较

数据报 (UDP)winsocket 的 C++ 问题通过环回适配器在同一套接字上发送和接收

java - DatagramChannel 绑定(bind)到通配符地址的 NoRouteToHostException