TCP和UDP的介绍及使用场景

article/2025/9/22 2:57:44

TCP和UDP的优势和劣势

TCP 最核心的价值是提供了可靠性,而 UDP 最核心的价值是灵活,你几乎可以用它来做任何事情。

例如:HTTP 协议 1.1 和 2.0 都基于 TCP,而到了 HTTP 3.0 就开始用 UDP 了。

TCP 的稳定性

TCP 作为一个传输层协议,最核心的能力是传输。传输需要保证可靠性,还需要控制流速,这两个核心能力均由滑动窗口提供

请求/响应模型

TCP 中每个发送的请求都需要响应。如果一个请求没有收到响应,发送方就会认为这次发送出现了故障,会触发重发。

排队(Queuing)

在这里插入图片描述

滑动窗口(Sliding Window)

在这里插入图片描述

如上图所示:

  • 深绿色代表已经收到 ACK 的段
  • 浅绿色代表发送了,但是没有收到 ACK 的段
  • 白色代表没有发送的段
  • 紫色代表暂时不能发送的段

将已发送的数据放到最左边,发送中的数据放到中间,未发送的数据放到右边。

假设我们最多同时发送 5 个封包,也就是窗口大小 = 5。窗口中的数据被同时发送出去,然后等待 ACK。如果一个封包 ACK 到达,我们就将它标记为已接收(深绿色)。

如下图所示,有两个封包的 ACK 到达,因此标记为绿色。

在这里插入图片描述

这个时候滑动窗口可以向右滑动,如下图所示:

在这里插入图片描述

重传

如果发送过程中,部分数据没能收到 ACK 会怎样呢?这就可能发生重传。

如果发生下图这样的情况,段 4 迟迟没有收到 ACK。

在这里插入图片描述

这个时候滑动窗口只能右移一个位置,如下图所示:
在这里插入图片描述

在这个过程中,如果后来段 4 重传成功(接收到 ACK),那么窗口就会继续右移。

如果段 4 发送失败,还是没能收到 ACK,那么接收方也会抛弃段 5、段 6、段 7。

这样从段 4 开始之后的数据都需要重发。

快速重传

在 TCP 协议中,如果接收方想丢弃某个段,可以选择不发 ACK。

发送端超时后,会重发这个 TCP 段。而有时候,接收方希望催促发送方尽快补发某个 TCP 段,这个时候可以使用快速重传能力。

例如段 1、段 2、段 4 到了,但是段 3 没有到。 接收方可以发送多次段 3 的 ACK。如果发送方收到多个段 3 的 ACK,就会重发段 3。这个机制称为快速重传。这和超时重发不同,是一种催促的机制。

为了不让发送方误以为段 3 已经收到了,在快速重传的情况下,接收方即便收到发来的段 4,依然会发段 3 的 ACK(不发段 4 的 ACK),直到发送方把段 3 重传。

思考:窗口大小的单位是?

在上面所有的图片中,窗口大小是 TCP 段的数量。

实际操作中,每个 TCP 段的大小不同,限制数量会让接收方的缓冲区不好操作,因此实际操作中窗口大小单位是字节数。

流速控制

发送、接收窗口的大小可以用来控制 TCP 协议的流速。

窗口越大,同时可以发送、接收的数据就越多,支持的吞吐量也就越大。

当然,窗口越大,如果数据发生错误,损失也就越大,因为需要重传越多的数据。

举个例子:我们用 RTT 表示 Round Trip Time,就是消息一去一回的时间。

假设 RTT = 1ms,带宽是 1mb/s。

如果窗口大小为 1kb,那么 1ms 可以发送一个 1kb 的数据(含 TCP 头),1s 就可以发送 1mb 的数据,刚好可以将带宽用满。

如果 RTT 再慢一些,比如 RTT = 10ms,那么这样的设计就只能用完 1/10 的带宽。 当然你可以提高窗口大小提高吞吐量,但是实际的模型会比这个复杂,因为还存在重传、快速重传、丢包等因素。

而实际操作中,也不可以真的把带宽用完,所以最终我们会使用折中的方案,在延迟、丢包率、吞吐量中进行选择。

滑动窗口是 TCP 协议控制可靠性的核心。发送方将数据拆包,变成多个分组。然后将数据放入一个拥有滑动窗口的数组,依次发出,仍然遵循先入先出(FIFO)的顺序,但是窗口中的分组会一次性发送。窗口中序号最小的分组如果收到 ACK,窗口就会发生滑动;如果最小序号的分组长时间没有收到 ACK,就会触发整个窗口的数据重新发送。另一方面,在多次传输中,网络的平均延迟往往是相对固定的,这样 TCP 协议可以通过双方协商窗口大小控制流速。

既然发送方有窗口,那么接收方也需要有窗口吗

接收方收到发送方的每个数据分组(或者称为 TCP Segment),接收方肯定需要缓存。

举例来说,如果发送方发送了:1, 2, 3, 4。 那么接收方可能收到的一种情况是:1,4,3。注意,没有收到 2 的原因可能是延迟、丢包等。这个时候,接收方有两种选择。

选择一:什么都不做(这样分组 2 的 ACK 就不会发送给发送方,发送方发现没有收到 2 的 ACK,过一段时间就有可能重发 2,3,4,5)。 当然具体设计还需要探讨,比如不重发整个分组,只重发已发送没有收到 ACK 的分组。

这种方法的缺陷是性能太差,重发了整个分组(或部分)。因此我们可以考虑另一种选择。

选择二:如果重发一个窗口,或部分窗口,问题就不会太大了。虽然增加了网络开销,但是毕竟有进步(1 进步了,不会再重发)。

性能方面最大的开销是等待超时的时间,就是发送方要等到超时时间才重发窗口,这样操作性能太差。

因此,TCP 协议有一个快速重传的机制——接收方发现接收到了 1,但是没有接收到 2,那么马上发送 3 个分组 2 的 ACK 给到发送方,这样发送方收到多个 ACK,就知道接收方没有收到 2,于是马上重发 2。

无论是上面哪种方案,接收方也维护一个滑动窗口,是一个不错的选择。接收窗口的状态,可以和发送窗口的状态相互对应了。

当接收方给发送方回复ack的时候会携带接收方窗口大小,发送方就会根据这个回复来动态调整自己的窗口大小。。双方协商,就是带上窗口大小。窗口大小通常是接收方说了算。

UDP 协议

UDP(User Datagram Protocol),目标是在传输层提供直接发送报文(Datagram)的能力。

为什么不直接调用 IP 协议呢? 如果裸发数据,IP 协议不香吗?

这是因为传输层协议在承接上方应用层的调用,需要提供应用到应用的通信——因此要附上端口号。每个端口,代表不同的应用。传输层下层的 IP 协议,承接传输层的调用,将数据从主机传输到主机。IP 层不能区分应用,导致哪怕是在 IP 协议上进行简单封装,也需要单独一个协议。这就构成了 UDP 协议的市场空间。

UDP 的封包格式

UDP 的设计目标就是在允许用户直接发送报文的情况下,最大限度地简化应用的设计。

UDP 的报文格式

在这里插入图片描述

UDP 的报文非常简化,只有 5 个部分。

  • Source Port 是源端口号。因为 UDP 协议的特性(不需要 ACK),因此这个字段是可以省略的。但有时候对于防火墙、代理来说,Source Port 有很重要的意义,它们需要用这个字段行过滤和路由。
  • Destination Port 是目标端口号(这个字段不可以省略)。
  • Length 是消息体长度
  • Checksum 是校验和,作用是检查封包是否出错。
  • Data octets 就是一个字节一个字节的数据,Octet 是 8 位。

校验和(Checksum)机制,这个机制在很多的网络协议中都会存在,因为校验数据在传输过程中有没有丢失、损坏是一个普遍需求。

比如现在数据有 4 个 byte:a,b,c,d,那么一种最简单的校验和就是:checksum=(a+b+c+d) ^ 0xff

如果发送方用上述方式计算出 Checksum,并将 a,b,c,d 和 Checksum 一起发送给接收方,接收方就可以用同样的算法再计算一遍,这样就可以确定数据有没有发生损坏变化)。

当然 Checksum 的做法,只适用于数据发生少量变化的情况。如果数据发生较大的变动,校验和也可能发生碰撞。

你可以看到 UDP 的可靠性保证仅仅就是 Checksum 一种。

如果一个数据封包 Datagram 发生了数据损坏,UDP 可以通过 Checksum 纠错或者修复。

但是 UDP 没有提供再多的任何机制,比如 ACK、顺序保证以及流控等。

UDP 与 TCP的区别

1. 目的差异

首先,这两个协议的目的不同:

  • TCP 协议的核心目标是提供可靠的网络传输

  • UDP 的目标是在提供报文交换能力基础上尽可能地简化协议轻装上阵

2. 可靠性差异

  • TCP 核心是要在保证可靠性提供更好的服务。TCP 会有握手的过程,需要建立连接,保证双方同时在线。而且TCP 有时间窗口持续收集无序的数据,直到这一批数据都可以合理地排序组成连续的结果。

  • UDP 并不具备以上这些特性,它只管发送数据封包,而且 UDP 不需要 ACK,这意味着消息发送出去成功与否 UDP 是不管的。

3. 连接 vs 无连接

  • TCP 是一个面向连接的协议(Connection-oriented Protocol),传输数据必须先建立连接。
  • UDP 是一个无连接协议(Connection-less Protocol),数据随时都可以发送,只提供发送封包(Datagram)的能力。

4. 流控技术(Flow Control)

  • TCP 使用了流控技术确保发送方不会因为一次发送过多的数据包而使接收方不堪重负。TCP 在发送缓冲区中存储数据,并在接收缓冲区中接收数据。当应用程序准备就绪时,它将从接收缓冲区读取数据。如果接收缓冲区已满,接收方将无法处理更多数据,并将其丢弃。
  • UDP 没有提供类似的能力。

5. 传输速度

  • UDP 协议简化,封包小,没有连接、可靠性检查等,因此单纯从传输速度上讲,UDP 更快

6. 场景差异

TCP 每个数据封包都需要确认,因此天然不适应高速数据传输场景,比如观看视频(流媒体应用)、网络游戏(TCP 有延迟)等。具体来说,

如果网络游戏用 TCP,每个封包都需要确认,可能会造成一定的延迟;再比如音、视频传输天生就允许一定的丢包率;

Ping 和 DNS Lookup,这类型的操作只需要一次简单的请求/返回,不需要建立连接,用 UDP 就足够了。

ping (Packet Internet Groper):因特网包探索器,用于测试网络连接量的程序

DNS Lookup(域名解析):请求某域名下的资源,浏览器需要先通过DNS解析器得到该域名服务器的IP地址。在DNS查找完成之前,浏览器不能从主机名那里下载到任何东西。

如果考虑希望传输足够块,就可能会用 UDP。

再比如 HTTP 协议,如果考虑请求/返回的可靠性,用 TCP 比较合适。

但是像 HTTP 3.0 这类应用层协议,从功能性上思考,暂时没有找到太多的优化点,但是想要把网络优化到极致,就会用 UDP 作为底层技术,然后在 UDP 基础上解决可靠性。

所以理论上,任何一个用 TCP 协议构造的成熟应用层协议,都可以用 UDP 重构

第一类:TCP 场景

  • 远程控制(SSH)
  • File Transfer Protocol(FTP)
  • 邮件(SMTP、IMAP)等
  • 点对点文件传出(微信等)

第二类:UDP 场景

  • 网络游戏
  • 音视频传输
  • DNS
  • Ping
  • 直播

第三类:模糊地带(TCP、UDP 都可以考虑)

  • HTTP(目前以 TCP 为主)
  • 文件传输

总结

  • UDP 的核心价值是灵活、轻量,构造了最小版本的传输层协议。
  • TCP 最核心的价值就是提供封装好的一套解决可靠性的优秀方案

解决可靠性是非常复杂的,要考虑非常多的因素。

  • TCP 帮助我们在确保吞吐量、延迟、丢包率的基础上,保证可靠性。

  • UDP 则不同,UDP 提供了最小版的实现,只支持 ChecksumUDP 最核心的价值是灵活、轻量、传输速度快

  • 最后还有一个非常重要的考虑因素就是成本,如果没有足够专业的团队解决网络问题,TCP 无疑会是更好的选择。

Moba 类多人竞技游戏的网络应该用 TCP 还是 UDP**?

Moba类游戏的传输协议是基于UDP的封装。首先Moba类游戏一般对实时性有要求,如果使用了TCP,再怎么优化也受TCP连接效率的影响。而UDP传输效率相对来说较高,但可靠性欠佳。因此思路应该是基于UDP协议做一些优化,牺牲部分的传输效率,保证其可靠性,但是又不需要像TCP协议那样有一套完善的机制来保证其可靠性。

文章参考《计算机网络通关 29 讲》—— 林䭽


http://chatgpt.dhexx.cn/article/9OdZEHfT.shtml

相关文章

Qt UDP和TCP对比

一、UPD和TCP区别总结 二、详细对比UDP和TCP如下: 1、TCP是面向连接的,UDP是面向无连接的 TCP则在通信前需要进行三次握手,UDP不需要。 UDP在发送端,应用层将数据传递给传输层的UDP协议,UDP只会给数据增加一个UDP头&…

UDP和TCP对比与区别

文章目录 UDP和TCP对比总对比1.udp是无连接的服务,tcp是面向连接的服务2.udp支持单播,多播以及广播;tcp仅支持单播3.udp面向报文,tcp面向字节流4.udp是不可靠传输,tcp是可靠传输5.udp数据报首部短,tcp报文段…

UDP和TCP的对比

用户数据报协议UDP(User Datagram Protocol)、传输控制协议TCP(Transmission Control Protocol) UDP和TCP是TCP/IP体系结构运输层中的两个重要协议,其使用频率仅次于网际层的IP协议 运输层采用面向连接的 TCP 协议时…

848-UDP 检验和 的计算过程

UDP 检验和 的计算过程 对发送方的 UDP 报文段的所有 16 比特字的和进行反码运算,当求和遇见溢出的时候,进行回卷(回卷的补充在下面),得到的结果放在 UDP 报文段中的检验和字段。 什么是回卷? 所谓 “回卷…

点估计 矩估计

1.说明: 设总体 X 的分布函数形式已知, 但它的一个或多个参数为未知, 借助于总体 X 的一个样本来估计总体未知参数的值的问题称为点估计问题. 在统计问题中往往先使用最大似然估计法, 在最大似然估计法使用不方便时, 再用矩估计法. 2.常用构造估计量的方法 1&#…

概率论-小记录(矩估计)

目录 矩估计量 无偏性-估计量的评选标准 一致估计量 矩估计量 定义: 矩估计法: 用样本k阶矩Ak作为总体k阶矩E(Xk)的估计量的方法. 注意最后用B2作为方差的矩估计量。 矩估计量不唯一 在总体的均值和方差都存在时,求均值μ和方差σ2 的矩估计量, 并不一定要知道…

矩估计和最大似然估计关系

1、矩估计 理论根源是辛钦大数定律,样本之间是独立同分布,当数据样本量很大的时候,样本观测值的平均值和总体的数学期望是在一个极小的误差范围内。 矩估计法, 也称“矩法估计”,就是利用样本矩来估计总体中相应的参数。首先推导…

数学:矩估计和最大似然估计

一、为什么要估计(estimate) 在概率,统计学中,我们所要观测的数据往往是很大的,(比如统计全国身高情况)我们几乎不可能去统计如此之多的值。这时候,就需要用到估计了。我们先抽取样本&#xff0…

矩估计和最大似然估计

参数估计 参数估计 :是根据从总体中抽取的样本估计总体分布中包含的未知参数的方法。它是统计推断的一种基本形式,是数理统计学的一个重要分支,分为点估计和区间估计两部分。 点估计 :依据样本估计总体分布中所含的未知参数或未…

广义矩估计

矩估计就是用样本矩代替总体矩进行统计推断的方法。 举例:正态参数估计问题, ,估计μ和σ。 ,而根据大数定理,在一定的条件下:当样本量足够大的时候,样本矩与总体矩只差了一个无穷小量&#xff…

机器学习总结(三):矩估计

鉴于后续机器学习课程中多次提到参数估计的概念,为了避免囫囵吞枣的理解某些知识点,决定对概率统计的这部分知识点进行简要总结,这篇博客主要涉及的是点估计中的矩估计知识点,后续的博客将总结点估计中其他两个比较常见的方式&…

参数估计-矩估计

​​​​​​​参数估计:分布类型有很多种,决定正态分布的两个参数:均值和方差。因此,参数就是决定分布的关键性数据。知道了参数,也就知道了分布的详细内容。 问题来了,总体的分布类别如果我们知道了&am…

矩估计与最大似然估计

一、为什么要估计(estimate) 在概率,统计学中,我们所要观测的数据往往是很大的,(比如统计全国身高情况)我们几乎不可能去统计如此之多的值。这时候,就需要用到估计了。我们先抽取样本&#xff0…

机器学习笔记1.矩估计、极大似然估计。

1.矩估计 1.1矩估计思想: 矩估计是基于一种简单的“替换”思想,即用样本矩估计总体矩 1.2矩估计理论: 矩估计的理论依据就是基于大数定律的,大数定律语言化表述为:当总体的k阶矩存在时,样本的k阶矩依概率收…

解决“至少有一个JAR被扫描用于TLD但尚未包含TLD”的问题

一、问题描述 26-Aug-2020 18:52:00.419 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期…

tld自定义标签之基础入门篇

一、tld说明 tld,是taglib description 的缩写,其自定义标签一般用于jsp页面,tld其作用一般是在web项目中结 jstl、c标签等用于有效性判断、权限判断等方面,对前端的一些页面标签起到约束、限制的作用。 很多人只知道有这类型的标…

至少有一个JAR被扫描用于TLD但尚未包含TLD。

问题描述: 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的JAR可以缩短启动时间和JSP编译时间。 一个或多个listeners启动失败,更多详细信息…

至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。

24-Jul-2022 17:18:15.259 信息 [RMI TCP Connection(3)-127.0.0.1] org.apache.jasper.servlet.TldScanner.scanJars 至少有一个JAR被扫描用于TLD但尚未包含TLD。 为此记录器启用调试日志记录,以获取已扫描但未在其中找到TLD的完整JAR列表。 在扫描期间跳过不需要的…

TLD的环境配置

TLD的matlab代码调试 建议matlab版本保证比vs版本高,不然会出现很多问题。例如找不到编译器,以及识别不了程序之类的 我调试的环境 VS2015 Matlab2016a OpenCV3.4.1,后面会出一个windows下使用cmake编译opencv扩展包 因为matlab是没有编译…