目录
TCP 三次握手
1. SYN (Synchronize:同步)
2. SYN-ACK (Synchronize + Acknowledge:同步+确认)
3. ACK (Acknowledge:确认)
为什么是三次而不是两次或四次?
三次握手的作用
TCP 四次挥手
第一次挥手:客户端发送 FIN
第二次挥手:服务器发送 ACK 确认
第三次挥手:服务器发送 FIN
第四次挥手:客户端发送 ACK 确认
为什么需要四次挥手?
TCP 三次握手
TCP三次握手(Three-Way Handshake) 是建立TCP连接时,客户端和服务器之间为了保证可靠的数据传输而进行的三次消息交换。 三次握手的目的是通过交换序列号,确认通信双方都准备好建立连接,并且双方都能进行数据的发送和接收。
注意: 三次握手只在TCP连接建立时进行一次,而不是在每次发送消息时都进行。因为 TCP是一个 面向连接的协议,这意味着在发送数据之前,客户端和服务器 需要建立一个持久的连接。这个连接在数据传输过程中保持开放,直到完成数据交换或者关闭连接。 三次握手是TCP连接建立的过程,一旦连接建立,客户端和服务器之间就可以进行多次数据传输,直到连接关闭。
1. SYN (Synchronize:同步)
- 客户端向服务器发送一个TCP包,SYN(同步)标志位为1,表示请求建立连接,并告诉服务器自己初始的序列号(seq。seq是一个随机值,这个序列号用于标识数据包的顺序,并且确保数据在传输过程中能够按照正确的顺序重组。使用随机的初始序列号可以防止一些网络攻击(比如猜测攻击),防止攻击者能够伪造合法的TCP连接)。
- 该包的目的就是告诉服务器:客户端准备建立连接,同时也告诉服务器客户端准备好数据流的初始序列号。
客户端 → 服务器
- SYN = 1
- 初始序列号:seq = x
2. SYN-ACK (Synchronize + Acknowledge:同步+确认)
- 服务器收到客户端的SYN包后,知道客户端要建立连接,于是服务器向客户端发送一个SYN-ACK包,表示服务器同意建立连接,并且确认客户端的序列号。
- SYN-ACK包包含两个标志位:
- SYN = 1:表示服务器同意连接。
- ACK = 1:表示确认收到了客户端的请求包。
- 同时,服务器会选定自己的序列号seq(如:y)并告知客户端,之后会根据这个序列号继续数据传输。
服务器 → 客户端
- SYN = 1
- ACK = 1
- 确认客户端序列号:ack = x + 1
- 初始序列号:seq = y
(SYN 是表示服务器同意与客户端建立连接,并且会告诉客户端服务器的初始序列号。ACK是表示确认收到客户端的 SYN请求包,即确认客户端发出的序列号 x,并且ACK中的确认号应是客户端的序列号 x + 1。)
3. ACK (Acknowledge:确认)
- 客户端收到服务器的SYN-ACK包后,确认服务器同意建立连接,并向服务器发送一个ACK包。此包用于确认服务器的 SYN包。
- 客户端在该包中会将序列号ack设置为服务器的初始序列号加1(即:ack = y + 1),同时客户端的序列号递增为x + 1。
客户端 → 服务器
- ACK = 1
- 确认服务器序列号:ack = y + 1
- 序列号:seq = x + 1
完成三次握手后,建立TCP连接,客户端和服务器可以开始正常的数据传输。
为什么是三次而不是两次或四次?
两次握手不足以保证服务器是否收到客户端的请求。如果客户端发送了SYN包,但服务器没有响应,客户端就无法知道服务器是否准备好接收连接。四次握手会增加额外的开销和延迟,而实际情况下三次握手就足够保证双方都准备好进行通信了。
三次握手的作用
- 保证双方准备好通信:通过交换序列号,客户端和服务器可以确保彼此都准备好接收和发送数据。
- 确认双方的接收能力:三次握手确保连接的两端都能够进行数据的发送和接收。
- 避免无效连接:如果客户端或服务器没有准备好,就不会建立连接,从而避免了无效连接的浪费。
TCP 四次挥手
四次挥手是 TCP 连接关闭的过程,确保客户端和服务器都能独立且正确地关闭各自的连接。客户端和服务器在关闭连接时需要分别发送 FIN 包,并且每个 FIN(Finish)包都需要对方的 ACK 确认,以保证双方都准备好关闭连接。
第一次挥手:客户端发送 FIN
客户端 -> 服务器:FIN(Finish)客户端向服务器发送一个 FIN 包(带有 FIN 标志),表示客户端没有数据要发送了,但仍然能够接收来自服务器的数据。此时客户端进入 FIN_WAIT_1 状态。
第二次挥手:服务器发送 ACK 确认
服务器 -> 客户端:ACK服务器收到客户端的 FIN 包后,确认客户端的关闭请求,发送一个 ACK 包(带有 ACK 标志)给客户端,确认号为客户端发送的序列号 + 1。此时,服务器进入 CLOSE_WAIT 状态,等待关闭其发送通道(即它需要先发送完自己未发送的数据)。客户端进入 FIN_WAIT_2 状态。
第三次挥手:服务器发送 FIN
服务器 -> 客户端:FIN(Finish)当服务器没有数据可发送并准备关闭连接时,服务器向客户端发送一个 FIN 包(带有 FIN 标志),表示服务器也没有数据要发送了。此时,服务器进入 LAST_ACK 状态。
第四次挥手:客户端发送 ACK 确认
客户端 -> 服务器:ACK
客户端收到服务器的 FIN 包后,发送一个 ACK 包(带有 ACK 标志)给服务器,确认号为服务器发送的序列号 + 1。此时,客户端进入 TIME_WAIT 状态,等待 2MSL(Maximum Segment Lifetime,最大报文生存时间),确保服务器收到了确认包。如果客户端在此时间段内没有收到重复的 FIN 包,它将彻底关闭连接。TIME_WAIT 状态也是为了防止网络延迟或丢包等问题,避免导致数据包的重发。)
服务器收到客户端的确认包后,进入 CLOSED 状态,连接完全关闭。
为什么需要四次挥手?
- TCP 是全双工的协议,即通信的双方(客户端和服务器)可以同时发送和接收数据。因此,关闭连接时,双方需要各自关闭自己的一条发送通道,才能完成连接的正常关闭。
- 每个方向上的数据传输都需要确认,确保数据不会丢失或错乱。