# 了解一下 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 三次握手
消息类型 | 描述 |
---|---|
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。
# TCP 四次挥手
在连接终止阶段使用四次挥手,连接的每一端都会独立的终止。下面我们来描述一下这个过程。
- 首先,客户端应用程序决定要终止连接(这里服务端也可以选择断开连接)。这会使客户端将 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
- 最后客户端发送 ACK 报文段有可能丢失,这样就会使得处于 LAST_ACK 状态的服务端由于收不到 对已发送的 FIN+ACK 报文段的确认,服务端超时重传 FIN+ACK 报文段,而客户端能在 2MSL 时间内收到这个重传的 FIN+ACK 报文段,接着客户端又发送一次 ACK 报文段,重新启动 2MSL 计时器,最后客户端和服务端都进入 CLOSED。如果没有这个 2MSL 时间,则导致服务端一直不能进入 CLOSED 状态
← HTTP和HTTPS Web Worker →