[后端知识] TCP和UDP

RoLingG 其他 2024-04-21

TCP和UDP

TCP和UDP简介

TCPUDP 都工作在 OSI 参考模型的第四层(传输层),其目的都是为了都是为了实现端到端的传输,传输各种文件。

TCP

TCP 的实现是基于连接的可靠数据通信。

TCP 进行传输,每一次数据的发送都需要得到对应的回应,是否接受数据、接受状态如何、数据顺序是否出错等等,在建立连接的基础上实现传输。

UDP

UDP 提供基于无连接的尽力而为的通信服务。

UDP 进行传输,只管将数据发送出去,但是不确定对方是否能够接受或者已经接受。UDP 只能尽自己的能力去发送,实现无连接的数据传输。

TCP连接过程

TCP 基于连接进行数据传输,主要过程有三步:三次握手、数据传输、四次挥手。

三次握手

TCP 三次握手是建立 TCP 连接时使用的一种协议。在进行数据通信之前,客户端和服务器之间需要通过三次握手来确认彼此的可靠性,以确保双方都准备好传输数据。以下是 TCP 三次握手的详细过程:

  • 第一次握手:客户端向服务器发送一个带有 SYN(同步序列编号)标志的数据包,表示请求建立连接。此时客户端进入 SYN_SENT 状态。
  • 第二次握手:服务器收到客户端发送的 SYN 数据包后,会回复一个带有 SYNACK 标志的数据包作为响应。ACK 是确认号,表示对客户端的 SYN 请求做出确认,并且自己也想要建立连接。此时服务器进入 SYN_RECV 状态。
  • 第三次握手:客户端收到服务器的响应后,会再次发送一个带有 ACK 标志的数据包给服务器,表示对服务器的确认。此时客户端和服务器都已经确认了彼此的请求,连接建立完成,双方可以开始进行数据传输。客户端进入 ESTABLISHED 状态,服务器在收到客户端的 ACK 后也进入 ESTABLISHED 状态。

请输入图片描述

简单来说就是:

客户端要送牛排,它把做好的牛排切条分盘,并把每盘编号。送到窗口让服务端去送,服务端为了保证这些盘的牛排是它负责送的,就将这些盘的牛排连编号拍了个照发给厨师客户端看并问了句这是它负责送的吗(ACK),客户端一看照片盘子编号、牛排条都对得上,就回服务端是(ACK)。于是两边就都确认了彼此工作没问题,互相信任对方(进入 ESTABLISHED 状态,这里可能比喻的不太对)
数据包来回传输本质就是用来确认传输是否成功的,客户端发送数据包(序列号+字节数据),服务端返回给客户端两者的和进行确认。保证可靠性
请输入图片描述

这样就构成了TCP三次握手。但这个过程中实际上接收方可能会因为处理数据能力不强或者带宽资源不够等因素导致数据溢出,传输数据失败。于是要控制好每次传输分包的个数。这也是为什么会有滑动窗口、拥塞控制等技术,目的就是为了控制好分包的个数。

四次挥手

TCP 四次挥手是在数据传输结束后,客户端和服务器断开 TCP 连接时使用的协议。通过四次挥手,双方可以优雅地关闭连接,并确保数据的完整性。以下是 TCP 四次挥手的详细过程:

  • 第一次挥手:客户端发送一个带有 FIN(结束)标志的数据包给服务器,表示客户端已经完成了数据传输并准备关闭连接。客户端进入 FIN_WAIT_1 状态。
  • 第二次挥手:服务器收到客户端发送的 FIN 数据包后,会回复一个 ACK 数据包作为确认。此时服务器进入 CLOSE_WAIT 状态,表示服务器已经知道客户端想要关闭连接。
  • 第三次挥手:一段时间后,服务器也准备好关闭连接时,服务器会发送一个带有 FIN 标志的数据包给客户端,表示服务器也准备关闭连接。服务器进入 LAST_ACK 状态。

    第三次挥手要等一段时间是为了等客户端接收完服务端传输的数据,这样做能避免客户端因网络IO、带宽速度等原因导致数据接收缺失。
  • 第四次挥手:客户端收到服务器的 FIN 数据包后,会回复一个 ACK 数据包作为确认。此时客户端进入 TIME_WAIT 状态,等待一段时间以确保服务器收到了最后的确认。服务器在接收到客户端的 ACK 后就进入 CLOSED 状态,连接完全关闭。

请输入图片描述

通过这个四次挥手的过程,客户端和服务器都可以完成连接的关闭,释放资源并终止对方的连接。在最后一次挥手完成后,双方的连接就正式关闭,不再传输数据。这种机制可以避免出现半开连接的情况,确保连接的安全关闭。

综上

通过这个三次握手过程,客户端和服务器能够建立起可靠的连接,并且双方都确认了彼此的通信能力。这种机制可以有效地防止因网络延迟或丢包等问题导致的连接异常,从而确保数据传输的可靠性。在数据传输结束后,双方可以通过四次挥手来关闭连接。

UDP连接过程

相比于 TCPUDP 的连接过程就很简单。

在原有数据包的基础之上,加上一些带有标识性的信息段,再通过网卡进行传输,之后不再关注该数据包的状态,从本质上来说,这些数据包之间并没有实质上的联系。所以,UDP 的数据包传输对于设备的计算损耗来说相当的小,可以大大的提高数据的传输速率。

举个简单的例子:

UDP 协议就相当于寄快递,将想要寄的东西(数据)打包好贴上地址联系人啥的(标识性信息段)给快递公司邮寄(网关)就行,之后的事就不用你再去关注了。

对比TCP和UDP

从上述 TCPUDP 的介绍我们就知道,实际使用上虽然 UDP 能够根据他的特性快速进行数据传递,但同时来说相比于 TCP ,它不能保证数据的稳定性与可靠性。换句话说,UDP 只有简单的网络收发能力,保证了它快;TCP 拥有重传滑动窗口拥塞控制等可靠性机制保证可靠性。TCP 就像套了多层壳的 UDP,可靠但是臃肿,速度慢了。

因此,TCP 的头部比 UDP 要大得多,TCP 的头部大小最小是20字节,而 UDP 头部固定是8字节大小。

简介概括起来:UDP 快,但是不稳。TCP 相对慢,但是又稳又可靠。

TCP 面向连接(如打电话要先拨号建立连接); UDP 是无连接的,即发送数据之前不需要建立连接。

TCP 要求安全性,提供可靠的服务,通过TCP连接传送的数据,不丢失、不重复、安全可靠。而UDP 尽最大努力交付,即不保证可靠交付。

TCP是点对点连接的,UDP一对一,一对多,多对多都可以

TCP传输效率相对较低,而UDP传输效率高,它适用于对高速传输和实时性有较高的通信或广播通信。

TCP适合用于网页,邮件等;UDP适合用于视频,语音广播等

TCP面向字节流,UDP面向报文

↑ UDP 没有确认号之类的可靠性保护内容,它的内容可能都是乱的,它会将应用层传输到传输层报文直接封装成数据段传输到网络层,不同的数据段之间会有明显的边界,而不是像 TCP 那样会对报文进行分片传输,TCP 传输的是有序列号和字节数据的字节流。(应用层可以给乱序的数据进行整理,所以还是可以不怎么用担心乱序问题)

UDP使用场景

通过上述,我们可以得出 UDP 适用于数据量小,但是高频发送的场景,且不那么要求数据可靠性与完整性的场景。

例如DNS服务就用的 UDP,DNS 服务为了保证查询效率,小数据量,要的是结果和效率,就很适合 UDP 大展身手。简单高效。还有例如语音软件和视频聊天等场景,即便数据传输导致卡一会也不怎么影响功能使用的,也适合 UDP 大展身手。

简单介绍KCP

那有什么办法保证又快又稳定?创建网络协议的人就在 TCPUDP 之间折中了一下,诞生了 KCP

KCP 简单来说就是少套了几层壳的 TCP,但更准确的说是保留少数几个重要的壳的 UDP

KCP 可以算是一种协议,但本质上来说是一种应用层算法。

重传机制

KCP 为了缓解 UDP 的丢包问题,使用了重传机制,这点与 TCP 相似。KCP 相比于 TCP 只需要等待1.5个 RTO 就能触发超时重传,传统 TCP 需要等2个 RTO

KCP 采用的是快速重传机制。TCP 需要有三个为1ACK 数据包才能触发重传;KCP只需要二个为1ACK 数据包就能触发重传

拥塞控制

TCP 检测到有丢包就会认为网络环境差,减少数据包传输的量。

KCP 也有这个策略,但不一样的是, KCP 可以关闭拥塞控制。当网络环境变差时,TCP 减少数据包传输的,这时候 TCP 进行拥塞控制相当于变相将网络资源让步给关闭拥塞控制KCP

例如:如果使用了 KCP 的实时监控视频网站,那么即便因网络问题视频数据传输丢包,也能通过 KCP 的特性让原本卡顿不清晰的画面变得相对清晰且流畅。

KCP的一些问题

这里重说回 KCP 的问题,在国内运营商内 UDP 传输的数据包如果在网络差的环境下是优先被丢弃的。如果要解决这种问题,一种是自己搭一个虚拟网络群,实现异地组网保证网络带宽高速且稳定。这一种解决方法技术要求和花费的成本都非常高。

KCP 其实本质上是介于用户代码UDP 之间的算法中间层,我们可以在 UDPKCP 之间加入前向纠错这一中间层来进行优化。这种做法是在数据包里冗余其他数据包的信息,这样就算有些数据包丢失了,也能通过其他数据包内冗余的信息去进行一部分的丢失信息还原。这样能保证在弱网环境下也能流畅的运行网络需求高的软件。

另外,在现在的时代里,UDP 协议使用的逐渐比 TCP 协议要多。这实际上并不是 TCP 不好,而是在现在网络硬件升级的越来越厉害、网络情况越来越好的时代下,TCP 那保持可靠与稳定性的各种机制反而显得 TCP 变得愈发的臃肿。

所以这也是为什么 UDP 正在逐渐的取代 TCP的原因。

PREV
[后端知识] GC回收
NEXT
[Redis学习] Redis集群相关模式

评论(0)

发布评论