TCP(传输控制协议)是面向连接的协议,它通过三次握手(Three-Way Handshake)和四次挥手(Four-Way Handshake)来建立和终止连接。下面是这两种过程的详细介绍:
一、TCP 三次握手(Three-Way Handshake)
三次握手是建立 TCP 连接的过程,用于确保客户端和服务器之间的连接建立时,双方都能够确认彼此的接收能力和发送能力。
三次握手的过程
-
第一次握手(SYN):
- 客户端向服务器发送一个
SYN
(同步)包,用于请求建立连接。 - 客户端选择一个初始序列号(ISN,Initial Sequence Number),并将该序列号放在
SYN
包中发送给服务器。 - 此时客户端进入 SYN_SEND 状态,等待服务器的确认。
客户端 → 服务器:
SYN = 1, Seq = x
(客户端发送的同步序列号为 x) - 客户端向服务器发送一个
-
第二次握手(SYN-ACK):
- 服务器收到客户端的
SYN
包后,回应一个SYN-ACK
包,表示服务器同意建立连接。 - 服务器也会选择一个自己的初始序列号,并在
SYN-ACK
包中发送给客户端。 - 同时,服务器会将客户端发送的
SYN
包中的序列号加 1,作为确认号(ACK)。
服务器 → 客户端:
SYN = 1, ACK = 1, Seq = y, Ack = x + 1
(服务器发送的同步序列号为 y,确认号为 x + 1) - 服务器收到客户端的
-
第三次握手(ACK):
- 客户端收到服务器的
SYN-ACK
包后,发送一个ACK
包给服务器,表示确认收到服务器的响应。 - 客户端在此包中将服务器的序列号加 1,作为确认号(ACK)。
客户端 → 服务器:
ACK = 1, Seq = x + 1, Ack = y + 1
(客户端发送的确认号为 y + 1) - 客户端收到服务器的
此时,连接建立成功,双方可以开始数据传输。
三次握手的作用
- 确保双方都知道连接的建立。
- 确保双方的缓冲区准备好接收数据。
- 同步双方的序列号,使得数据能够按顺序正确地传输。
二、TCP 四次挥手(Four-Way Handshake)
四次挥手是断开 TCP 连接的过程。在断开连接时,需要双方的确认,以确保数据已完全传输,且连接已经被正确关闭。
四次挥手的过程
-
第一次挥手(FIN):
- 客户端(或主动关闭连接的一方)向服务器发送一个
FIN
包,表示客户端不再发送数据。 - 此时,客户端进入 FIN_WAIT_1 状态,等待服务器确认。
FIN
包会携带一个序列号,表示客户端最后发送的数据包的序列号。
客户端 → 服务器:
FIN = 1, Seq = x
- 客户端(或主动关闭连接的一方)向服务器发送一个
-
第二次挥手(ACK):
- 服务器收到
FIN
包后,向客户端发送一个ACK
包,确认客户端的FIN
包。 - 服务器进入 CLOSE_WAIT 状态,等待客户端的进一步请求或处理。
ACK
包的确认号为客户端的序列号加 1,表示确认客户端已经成功关闭发送方向的连接。
服务器 → 客户端:
ACK = 1, Seq = y, Ack = x + 1
- 服务器收到
-
第三次挥手(FIN):
- 服务器准备好关闭连接后,向客户端发送一个
FIN
包,表示服务器也不再发送数据。 - 服务器进入 LAST_ACK 状态,等待客户端的确认。
- 服务器发送的
FIN
包携带一个序列号,表示服务器最后发送的数据包的序列号。
服务器 → 客户端:
FIN = 1, Seq = y
- 服务器准备好关闭连接后,向客户端发送一个
-
第四次挥手(ACK):
- 客户端收到服务器的
FIN
包后,发送一个ACK
包给服务器,确认服务器的FIN
包。 - 客户端进入 TIME_WAIT 状态,保持一段时间,以确保服务器收到了确认包后才最终关闭连接。
- 客户端的确认号为服务器的序列号加 1。
客户端 → 服务器:
ACK = 1, Seq = x + 1, Ack = y + 1
- 客户端收到服务器的
此时,连接关闭成功,双方都可以释放各自的资源。
四次挥手的作用
- 确保双方都能够完成数据传输,并确认双方都关闭了连接。
- 确保数据传输的完整性和一致性,在关闭连接时不会丢失数据。
- 客户端会在
TIME_WAIT
状态下等待一段时间,确保服务器接收到确认包,这样可以防止老的重复数据包影响新连接。
注意事项:
- TIME_WAIT 状态:在第四次挥手后,客户端进入
TIME_WAIT
状态,持续等待 2MSL(Maximum Segment Lifetime,最大报文生存时间)。这个时间可以确保最后的确认包到达对方,同时防止重复数据包的干扰。 - FIN 和 ACK 包:TCP 连接的关闭是双方共同完成的,双方都需要发送
FIN
包来表示关闭连接。每个FIN
包都需要一个确认包(ACK
)作为回应。
总结
-
三次握手:用于建立连接,确保双方的缓冲区和序列号同步。
- 客户端发送
SYN
→ 服务器发送SYN-ACK
→ 客户端发送ACK
。
- 客户端发送
-
四次挥手:用于关闭连接,确保双方都完成了数据的传输并正确关闭连接。
- 客户端发送
FIN
→ 服务器发送ACK
→ 服务器发送FIN
→ 客户端发送ACK
。
- 客户端发送
这两种机制是 TCP 可靠传输的基础,保证了数据传输的稳定性和连接的可靠管理。
三、常见问题
一、为什么不能使用二次握手(Two-Way Handshake)?
二次握手是指在建立连接时,只经过两次交互即可完成。它理论上可以简化连接的建立过程,但这样做会存在非常严重的风险,特别是在可靠性和数据完整性方面。
TCP 连接的可靠性要求
TCP 是一种面向连接的协议,它需要保证:
- 双方都能够接收数据。
- 双方的序列号保持一致,以确保数据按顺序接收。
- 双方都已经准备好发送和接收数据。
三次握手的步骤(SYN → SYN-ACK → ACK)有助于:
- 确保双方都能接收数据:客户端通过发送
SYN
包告知服务器它希望连接,并且能够接收数据。服务器通过SYN-ACK
确认它的接收能力并给出自己的初始序列号,表示它准备接收数据。客户端再次发送ACK
确认服务器已经准备好连接,双方的序列号同步。 - 防止旧连接的干扰:三次握手可以确保双方的序列号是同步的。没有三次握手,可能会有问题,比如来自旧连接的数据被误认为是新连接的数据,造成混乱。
如果只有二次握手:
- 客户端和服务器在没有确认彼此序列号的情况下就开始发送数据,这样会导致数据的顺序和完整性无法保证。
- 如果客户端或服务器在未完成连接建立之前就中断了,接收方可能会收不到确认,导致连接状态的不一致。
因此,二次握手是不安全且不可靠的,无法确保双方的接收能力和数据顺序的同步。
二、为什么四次挥手结束后要等待 2MSL(Maximum Segment Lifetime)?
在 TCP 中,四次挥手(Four-Way Handshake)用于正确地断开连接,确保双方都能完全终止通信,并且数据被正确传输和接收。然而,TCP 连接的关闭需要在一个适当的时间等待,以防止潜在的重复数据包干扰新的连接。
1. 解释 TIME_WAIT
状态
当 客户端(或主动关闭连接的一方)发送 FIN
包后,进入 TIME_WAIT 状态。客户端会在此状态下保持一段时间(通常为 2 * MSL):
- MSL(Maximum Segment Lifetime) 是一个网络中的时间参数,表示 TCP 分段(即数据包)可以在网络中存在的最大时间。
- 在
TIME_WAIT
状态下,客户端保持这个连接 2 * MSL 时间,目的是:- 确保服务器收到最后的确认包:如果客户端发送了
ACK
包来确认服务器的FIN
包,但由于某些原因(例如网络延迟、丢包等),服务器没有收到ACK
包,那么服务器可能会重发FIN
包。客户端需要确保能够接收到这种重发的数据包,并对此作出回应。 - 防止旧的重复数据包影响新连接:网络中的老数据包在某些情况下可能会在连接关闭后仍然存在,特别是在网络拥堵或路由不稳定的情况下。如果没有 2 * MSL 时间的等待,旧的数据包可能会在未来的连接中造成干扰(比如新连接和旧连接使用相同的端口和 IP 地址)。通过等待 2 * MSL 时间,可以确保旧的数据包已经从网络中消失,不会影响之后的连接。
- 确保服务器收到最后的确认包:如果客户端发送了
2. 为什么是 2 * MSL?
- 1 * MSL:这是网络中一个数据包在网络中传递的最长时间。它代表了一个数据包能够在网络中生存的最大时间。
- 2 * MSL:考虑到数据包在两端之间的往返时间(RTT),而且在某些情况下,服务器可能会重发
FIN
包。因此,客户端必须等待两倍的 MSL 时间,以确保:- 接收到服务器的最后确认。
- 确保没有来自于旧连接的重复数据包。
3. 示例说明
假设客户端主动发起连接关闭:
- 客户端发送
FIN
包。 - 服务器回复
ACK
并发送FIN
包。 - 客户端回复确认
ACK
。
此时,客户端进入 TIME_WAIT
状态,等待 2 * MSL 时间。此时:
- 如果服务器未收到客户端的
ACK
包,它会重发FIN
包。客户端会收到并再次发送确认,确保连接完全关闭。 - 如果某些网络包因网络延迟而延迟到达客户端,这些包不会影响新的连接。
4. 为什么不能直接关闭连接?
在没有等待 2 * MSL 时间的情况下,若有老的数据包滞留在网络中,它们可能会与后续的连接产生冲突,导致数据丢失或者错误的连接状态。为了避免这种情况,TIME_WAIT 状态是必要的。
总结
- 三次握手是 TCP 连接建立的必要步骤,确保双方能够接收数据并且同步序列号。二次握手无法确保连接的可靠性。
- 四次挥手用于正确关闭连接,确保双方都完成数据传输,避免数据丢失。客户端在断开连接后需要等待 2 * MSL 时间,以确保所有数据包都能够完全从网络中消失,并防止潜在的旧数据包影响新的连接。