# 了解一下 TCP 和 UDP 知识

# UDP 是什么?

UDP 的全称是 User Datagram Protocol,用户数据报协议。它不需要所谓的握手操作,从而加快了通信速度,允许网络上的其他主机在接收方同意通信之前进行数据传输。

数据报是与分组交换网络关联的传输单元。

UDP 的特点主要有

  • UDP 能够支持容忍数据包丢失的带宽密集型应用程序
  • UDP 具有低延迟的特点
  • UDP 能够发送大量的数据包
  • UDP 能够允许 DNS 查找,DNS 是建立在 UDP 之上的应用层协议。

# TCP 是什么?

TCP 的全称是Transmission Control Protocol ,传输控制协议。它能够帮助你确定计算机连接到 Internet 以及它们之间的数据传输。通过三次握手来建立 TCP 连接,三次握手就是用来启动和确认 TCP 连接的过程。一旦连接建立后,就可以发送数据了,当数据传输完成后,会通过关闭虚拟电路来断开连接。

TCP 的主要特点有

  • TCP 能够确保连接的建立和数据包的发送
  • TCP 支持错误重传机制
  • TCP 支持拥塞控制,能够在网络拥堵的情况下延迟发送
  • TCP 能够提供错误校验和,甄别有害的数据包。

# TCP 和 UDP 的不同

TCP UDP
TCP 是面向连接的协议 UDP 是无连接的协议
TCP 在发送数据前先需要建立连接,然后再发送数据 UDP 无需建立连接就可以直接发送大量数据
TCP 会按照特定顺序重新排列数据包 UDP 数据包没有固定顺序,所有数据包都相互独立
TCP 传输的速度比较慢 UDP 的传输会更快
TCP 的头部字节有 20 字节 UDP 的头部字节只需要 8 个字节
TCP 是重量级的,在发送任何用户数据之前,TCP 需要三次握手建立连接。 UDP 是轻量级的。没有跟踪连接,消息排序等。
TCP 会进行错误校验,并能够进行错误恢复 UDP 也会错误检查,但会丢弃错误的数据包。
TCP 有发送确认 UDP 没有发送确认
TCP 会使用握手协议,例如 SYN,SYN-ACK,ACK 无握手协议
TCP 是可靠的,因为它可以确保将数据传送到路由器 在 UDP 中不能保证将数据传送到目标。
TCP 适用于要求可靠传输的应用,例如文件传输 UDP 适用于实时应用(IP 电话、视频会议、直播等)

# TCP 三次握手和四次挥手

TCP 三次握手和四次挥手过程 (opens new window)

# TCP 三次握手

消息类型 描述
SYN 这个消息是用来初始化和建立连接的。
ACK 帮助对方确认收到的 SYN 消息
SYN-ACK 本地的 SYN 消息和较早的 ACK 数据包
FIN 用来断开连接
  • SYN:它的全称是 Synchronize Sequence Numbers,同步序列编号。是 TCP/IP 建立连接时使用的握手信号。在客户机和服务器之间建立 TCP 连接时,首先会发送的一个信号。客户端在接受到 SYN 消息时,就会在自己的段内生成一个随机值 X。
  • SYN-ACK:服务器收到 SYN 后,打开客户端连接,发送一个 SYN-ACK 作为答复。确认号设置为比接收到的序列号多一个,即 X + 1,服务器为数据包选择的序列号是另一个随机数 Y。
  • ACK:Acknowledge character, 确认字符,表示发来的数据已确认接收无误。最后,客户端将 ACK 发送给服务器。序列号被设置为所接收的确认值即 Y + 1。

img

# TCP 四次挥手

在连接终止阶段使用四次挥手,连接的每一端都会独立的终止。下面我们来描述一下这个过程。

img

  • 首先,客户端应用程序决定要终止连接(这里服务端也可以选择断开连接)。这会使客户端将 FIN 发送到服务器,并进入 FIN_WAIT_1 状态。当客户端处于 FIN_WAIT_1 状态时,它会等待来自服务器的 ACK 响应。
  • 然后第二步,当服务器收到 FIN 消息时,服务器会立刻向客户端发送 ACK 确认消息。
  • 当客户端收到服务器发送的 ACK 响应后,客户端就进入 FIN_WAIT_2 状态,然后等待来自服务器的 FIN 消息
  • 服务器发送 ACK 确认消息后,一段时间(可以进行关闭后)会发送 FIN 消息给客户端,告知客户端可以进行关闭。
  • 当客户端收到从服务端发送的 FIN 消息时,客户端就会由 FIN_WAIT_2 状态变为 TIME_WAIT 状态。处于 TIME_WAIT 状态的客户端允许重新发送 ACK 到服务器为了防止信息丢失。客户端在 TIME_WAIT 状态下花费的时间(2MSL)取决于它的实现,连接关闭,客户端上所有的资源(包括端口号和缓冲区数据)都被释放

# 面试相关

# 为什么要有第三次握手,二次握手不行吗?

主要是为了防止已失效的连接请求报文字段突然又传到了服务端,因而产生错误。

比如客户端发出第一个连接请求,但是因为报文丢失该请求失效了,于是客户端又重新发送一个连接请求,这一次正常连接,数据传输完毕后释放连接。在这过程中,客户端发出了两个连接请求,一个得到了确认,一个只是在某些网络结点长时间滞留了,延误到第二次连接释放后的某个时间到达服务端,这时候服务端进行第二次握手,如果只有两次握手,这时候请求已经建立了,但由于客户端不理睬服务端且不发送任何数据,就会导致服务端一直等待,浪费资源

# 服务端容易受到 SYN 攻击?为什么?怎么办?

由于服务端的资源分配是在第二次握手时发生的,客户端的资源分配是在第三次握手时发生的,因此服务器容易受到 SYN 洪泛攻击,SYN 攻击就是客户端在短时间内伪造大量不存在的 IP 地址,并向服务端不断发送 SYN 包,服务端则回复 SYN 并等待客户端确认,由于 IP 地址不存在,所以服务端需要不断重发直至超时,这些 SYN 包将长时间占用未连接队列,导致正常的 SYN 请求因为队列满而被丢弃,从而引起网络拥塞甚至系统瘫痪

防范措施:

  • 降低主机的等待时间,使主机尽快释放半连接的占用
  • 短时间内收到某 IP 的重复的 SYN 包则丢弃后续请求

# 为什么客户端 TIME_WAIT 状态必须等待 2MSL 的时间再进入 COLSED?

MSL:最长报文段寿命(Maximum Segment Lifetime),MSL= 2

  1. 最后客户端发送 ACK 报文段有可能丢失,这样就会使得处于 LAST_ACK 状态的服务端由于收不到 对已发送的 FIN+ACK 报文段的确认,服务端超时重传 FIN+ACK 报文段,而客户端能在 2MSL 时间内收到这个重传的 FIN+ACK 报文段,接着客户端又发送一次 ACK 报文段,重新启动 2MSL 计时器,最后客户端和服务端都进入 CLOSED。如果没有这个 2MSL 时间,则导致服务端一直不能进入 CLOSED 状态
最近更新: 4 小时前