UDP 协议和 TCP 协议

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 本文介绍了UDP和TCP协议的基本结构与特性。UDP协议具有简单的报文结构,包括报头和载荷,报头由源端口、目的端口、报文长度和校验和组成。UDP使用CRC校验和来检测传输错误。相比之下,TCP协议提供更可靠的传输服务,其结构复杂,包含序列号、确认序号和标志位等字段。TCP通过确认应答和超时重传来保证数据传输的可靠性,并采用三次握手建立连接,四次挥手断开连接,确保通信的稳定性和完整性。

1. UDP 协议结构

报文格式:

UDP 的报文分为报头,正文/载荷(完整的应用层数据包),其中报头部分又分为四个部分,每一个部分都是固定的四个字节,分别存储源端口,目的端口,UDP 报文长度(报文长度 = 报头长度 + 载荷长度),校验和(检验和),每一个部分都是固定的两个字节存储,由于是两个字节存储 UDP 报文长度,所以最大值就是 65535 ,也就是 64KB ,这个时候就会出现一个问题,如果要表示的内容不止是 64KB ,就需要换用 TCP 来表示了

关于校验和:由于网络传输过程中是比较容易出现错误的,传输的电信号/光信号/电磁波等信息容易受到环境的干扰,使这里的传输信号发生转变,校验和的目的就是能够“发现”或者“纠正”这些错误,同时,如果只是发现错误,那么校验和携带的信息就可以很少,如果想要纠正错误,就需要再携带额外的信息(消耗更多的带宽)

在 UDP 协议中使用的简单有效的校验和是 CRC 校验和(循环冗余校验):对 UDP 数据报整个进行遍历,分别取出每一个字节,往一个字节或是两个字节的变量上进行累加,即使溢出之后也继续加,主要关注的是校验和的结果是否会在传输中改变

如果说传输的数据,在网络通信中没有发生任何改变,此时计算出来的就是 checksum1 == checksum2 反之,如果不相等,就代表数据传输中数据发生了改变,就会丢弃这次传输

此外还可能会发生传输过程中校验和的信息也发生改变了,也就是传输过程中校验和变成了 checksum3,此时接收方重新计算校验和得到了 checksum4 ,这种情况下两个校验和大概率是不相等的,所以影响也不大,还有可能出现两组不同的数据计算出相同的校验和,这种概率也是非常低的,所以上面这两种极端情况一般不考虑


MD5 算法:

本质上是一个“字符串 hash 算法”,特点:

  1. 定长:无论输入多长的字符串,得到的结果都是固定长度(适合做校验算法)
  2. 分散:输入的内容只要发生一点改变,得到的结果也是相差很大的(适合做哈希算法)
  3. 不可逆:根据输入的内容计算 md5 对计算机来说是不复杂的,但是如果根据 md5 的值来计算原始值,理论上是不可以的(适合做加密算法)

2. TCP 协议

2.1. 协议结构

2.2. 确认应答

在之前提到过 TCP 的核心机制是确认应答,可以确认对方是否收到数据,在数据传输的过程中,如果有多条请求,并且返回对应的响应,但是此时可能会出现这样的问题:最先发送的请求可能并不会最先收到响应,也就是收到响应的顺序会不一样。

针对这样的问题的解决方案就是给每一个字节都进行编号(TCP 的传输是面向字节流的),并且编号是连续且递增的,按照字节编号这样的机制就称为“TCP 的序号”,在应答报文中,针对之前收到的数据进行对应的编号,称为“TCP 的确认序号”

上面的 32 位序列号和确认序列号就是这种,由于序号是递增的,知道了第一个字节的序号,后续每一个字节的序号都能知道

假如 TCP 发送了的数据标记为了 1~1000,那么确认应答的序号应该是收到的数据最后一个字节序号的下一个序号,也就是1001,表示小于 1001 序号的数据都收到了

并且之后的六位标志位中的第二位(ack)就会设为 1(默认是0)

2.3. 丢包

丢包的原因:

  1. 数据传输过程中发生了 bit 翻转,收到这个数据的接收方/中间的路由器等,计算校验和发现不匹配,就会把当前数据包丢掉,不再交给应用层
  2. 数据传输到某个节点(路由器/交换机)时,当前节点负载过高,例如某个路由器单位时间内只能发送n 个包,但是遇到了高峰期,单位时间内需要发送的包超过了 n ,后续传输过来的数据就可能被路由器丢掉了

2.4. 超时重传

TCP 对抗丢包的方法:其实丢包是不可能避免的,TCP 感应到丢包之后就会再重新发一次数据,第二次再发生丢包的概率就会减小很多,TCP 感应丢包是通过应答报文来区分的,收到应答报文之后就说明没有丢包,没有收到应答报文就说明数据丢包了,但是也不能排除当时没收到后续收到了的情况,所以就需要设置一个时间限制,在时间限制内来判断是否丢包,不过还有一个特殊情况:

第一种就是正常的数据没有发送到丢包了,第二种是数据没有丢,但是 ack 丢了,不过无论是哪种情况都会认为是丢包并且进行数据重传,这时就会出现一个问题,第一种情况是没问题的,数据丢了重新传,但是第二种情况数据没有丢,再次发送就意味着主机2收到了两份同样的数据,如果是转账的请求,让你转两次账肯定也不合理

针对上述问题 TCP 也进行了处理,接收方会有一个接收缓冲区,收到的数据会先进入缓冲区中,后续再收到数据就会根据序号在缓冲区中找对应的位置,如果发现当前序号 1~1000 已经存在了,就会把新收到的数据丢弃了,以此来确保读取到的数据是唯一的

重传的时间设定:

这里的时间不是固定的,而是动态变化的,例如发送方第一次重传,超时时间为 t1,如果重传之后仍然没有 ack ,还是继续重传,第二次重传超时时间为 t2,,t2 是大于 t1 的,每多重传一次,超时时间的间隔就会变大

经过一次重传之后,就能让数据到达对方的概率显著提示,反之,如果重传几次都没有顺利到达,说明网络的丢包率已经达到了一个很大的程度

重传也不会无休止的进行,当重传到达一定次数的时候,TCP 就不会尝试重传了,就认为这个链接已经G了,此时先进行“重置/复位 连接”,发送一个特殊的数据包“复位报文”,如果网络恢复了,复位报文就会重置连接,使通信继续进行,如果网络还是有问题,复位报文没有得到回应,此时 TCP 就会单方面放弃连接

确认应答和超时重传这两个核心机制共同构建了 TCP 的“可靠传输机制”

2.5. TCP 的三次握手

三次确保了客户端和服务器之间建立连接,发送不携带业务数据(没有载荷,只有报头)的数据包

客户端发送同步请求,也就是标志位中的第 5 位,然后服务端也回应发送同步信息和确认应答,客户端再确认应答,虽然说看上去是四次交互,但是中间服务器的 syn + ack 合并了,一起发送到客户端,也就是三次握手

TCP 进行三次握手的原因:

  1. 验证通信路径是否畅通。
  2. 验证通信双方的发送能力和接收能力是否正常,客户端第一次发送 syn 可以确定客户端的发送能力和服务器的接收能力正常,然后服务器发送 syn + ack 告诉客户端的发送能力和服务器的接收能力正常,然后客户端就知道了自己的接收和发送能力都正常,再发送 ack ,服务器也确认了自己的发送能力正常
  3. 让通信双方在进行通信之前,对通信过程中需要用到的一些关键参数进行协商(例如确定起始序号,TCP 通信时,起始数据的序号就是通过三次握手协商确定的,每次建立连接 TCP 的其实序号都不同,并且差别很大,这样做是为了避免上一次的数据如果“迷路了”,在下一次 TCP 连接时出现误判,如果发现不是属于此次起始范围的数据就丢弃)

2.6. TCP 的四次挥手

  1. 客户端完成数据发送任务后,发送一个带有 FIN(终止)标志位的数据包,用来关闭客户端到服务器的数据传送。此时客户端进入 FIN_WAIT_1 状态,表示客户端不再向服务器发送数据,但仍可以接收服务器发送的数据。
  2. 服务器收到客户端的 FIN 包后,发回一个 ACK 数据包给客户端,确认序号为收到的序号加 1。此时服务器进入 CLOSE_WAIT 状态,表明服务器还有数据可能需要发送给客户端,客户端收到这个 ACK 后进入 FIN_WAIT_2 状态,继续等待服务器的 FIN 报文
  3. 当服务器端确定数据已发送完成,则向客户端发送 FIN 报文,告诉客户端自己也要断开连接了,然后服务器进入 LAST_ACK 状态,等待客户端的确认
  4. 客户端收到服务器的 FIN 报文后,回复一个 ACK 报文给服务器,确认号为收到的序号加 1,随后客户端进入 TIME_WAIT 状态。服务器收到这个 ACK 报文后,连接正式关闭,进入 CLOSED 状态。客户端在经过 2 倍的 MSL(报文最大生存时间)后,也进入 CLOSED 状态

状态说明:

LISTEN:服务器进入的状态,服务器把端口绑定好之后相当于进入了该状态,等待客户端发生请求

ESTABLISHED:客户端和服务器都会进入的状态,表示 TCP 已经建立好连接了

CLOSE_WAIT:被动断开连接的一方(先收到 FIN)会进入这个状态,等待代码执行 close 方法

TIME_WAIT:主动断开连接的一方会进入这个状态,按照时间来等待,达到一定时间后等待结束(原因:防止最后一个 ACK 丢包),时间就是 2 倍的 MSL(报文最大生存时间)

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
10天前
|
网络协议 算法 网络性能优化
|
4天前
|
缓存 负载均衡 网络协议
面试:TCP、UDP如何解决丢包问题
TCP、UDP如何解决丢包问题。TCP:基于数据块传输/数据分片、对失序数据包重新排序以及去重、流量控制(滑动窗口)、拥塞控制、自主重传ARQ;UDP:程序执行后马上开始监听、控制报文大小、每个分割块的长度小于MTU
|
20天前
|
网络协议 前端开发 物联网
TCP和UDP区别?
本文首发于微信公众号“前端徐徐”,详细介绍了TCP和UDP两种传输层协议的核心概念、连接性和握手过程、数据传输和可靠性、延迟和效率、应用场景及头部开销。TCP面向连接、可靠、有序,适用于网页浏览、文件传输等;UDP无连接、低延迟、高效,适用于实时音视频传输、在线游戏等。
31 1
TCP和UDP区别?
|
12天前
|
Web App开发 缓存 网络协议
不为人知的网络编程(十八):UDP比TCP高效?还真不一定!
熟悉网络编程的(尤其搞实时音视频聊天技术的)同学们都有个约定俗成的主观论调,一提起UDP和TCP,马上想到的是UDP没有TCP可靠,但UDP肯定比TCP高效。说到UDP比TCP高效,理由是什么呢?事实真是这样吗?跟着本文咱们一探究竟!
40 10
|
22天前
|
网络协议 网络性能优化 C#
C# 一分钟浅谈:UDP 与 TCP 协议区别
【10月更文挑战第8天】在网络编程中,传输层协议的选择对应用程序的性能和可靠性至关重要。本文介绍了 TCP 和 UDP 两种常用协议的基础概念、区别及应用场景,并通过 C# 代码示例详细说明了如何处理常见的问题和易错点。TCP 适用于需要可靠传输和顺序保证的场景,而 UDP 适用于对延迟敏感且可以容忍一定数据丢失的实时应用。
26 1
|
28天前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
35 0
Linux C/C++之TCP / UDP通信
|
1月前
|
网络协议 算法 数据格式
【TCP/IP】UDP协议数据格式和报文格式
【TCP/IP】UDP协议数据格式和报文格式
82 3
|
1月前
|
存储 网络协议 Java
【网络】UDP和TCP之间的差别和回显服务器
【网络】UDP和TCP之间的差别和回显服务器
56 1
|
1月前
|
存储 网络协议 算法
更深层次理解传输层两协议【UDP | TCP】【UDP 缓冲区 | TCP 8种策略 | 三次握手四次挥手】
UDP和TCP各有所长,UDP以其低延迟、轻量级的特点适用于对实时性要求极高的应用,而TCP凭借其强大的错误检测、流量控制和拥塞控制机制,确保了数据的可靠传输,适用于文件传输、网页浏览等场景。理解它们的工作原理,特别是UDP的缓冲区管理和TCP的8种策略,对于优化网络应用的性能、确保数据的高效和可靠传输至关重要。开发者在选择传输层协议时,应根据实际需求权衡利弊,合理利用这两项关键技术。
53 5
|
1月前
|
JavaScript 安全 Java
谈谈UDP、HTTP、SSL、TLS协议在java中的实际应用
下面我将详细介绍UDP、HTTP、SSL、TLS协议及其工作原理,并提供Java代码示例(由于Deno是一个基于Node.js的运行时,Java代码无法直接在Deno中运行,但可以通过理解Java示例来类比Deno中的实现)。
60 1