什么是三次握手与四次挥手?
三次握手(握手连接)
三次握手是客户端与服务器端建立连接的过程
三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。
- 第一次握手:当客户端向服务端发起连接时,会先发一包连接请求数据,询问一下服务器端,能否与你建立连接,这包数据我们称之为
SYN
(SYN chronization
) 同步)包,并指明客户端的初始化序列号ISN
(Initial Sequence Number),此时客户端处于SYN_SEND
状态(同步发送)
数据报文中:同步位
SYN
=1,初始序号ISN
=x
- 第二次握手:服务器收到客户端的
SYN
报文之后,会以自己的SYN
报文作为应答,并且也是指定了自己的初始化序列号ISN
。同时会把客户端的ISN
+ 1 作为ACK
的值,表示自己已经收到了客户端的SYN
,此时服务器处于SYN_REVD
的状态。
这个数据包中,序列号(
ISN
)是服务器随机产生的一个值,ACK
确认号是客户端的初始序列号+1 = x+1,服务器端的初始序号=y
- 第三次握手:客户端收到
SYN
报文之后,会发送一个ACK
报文,当然,也是一样把服务器的ISN + 1
作为ACK
的值,表示已经收到了服务端的SYN
报文,此时客户端处于ESTABLISHED(已确立的)
状态。服务器收到ACK
报文之后,也处于ESTABLISHED(已确立的)
状态,此时,双方已建立起了连接。
在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y
此时连接建立
因为整个过程中,互相发送了三包数据,所以称之为三次握手!
为什么需要三次,而不是两次握手?客户端发送 SYN 包,服务器端返回 SYN +
ACK
表示双方都准备OK!为什么还要客户端多返回一次ACK
包?
- 客户端发送一个SYN包给客户端,因为某些位置原因,导致这个SYN包没有成功发送给服务端,在某个网络节点产生了滞留
- 客户端,为了建立连接,因为没收到服务端的回复,再次发送一个新的SYN包,这次数据包正常送达,服务器端返回给客户端一个
SYN
+ACK
的包,连接建立 - 但是之前阻塞的网络节点突然恢复,第一包的
SYN
数据包发送给了服务器端,服务器端会误认为客户端又发起了一个新的连接,服务器端又为当前客户端开启了新的连接
此时,服务端认为是两个连接,客户端认为是一个连接,导致连接状态不一致的情况发生.
所以最后一次客户端发送的的ACK
包,就是保证连接的一致性,在不可靠的信道上,建立可靠的连接.
比较简洁的描述这三次握手的过程:
- 客户端发送:你好,我是 12138
- 服务的发送:你好,我是 123456服务器,连接确认码 12139
- 客户端发送:你好,确认码确认成功,我已经进入连接状态,当前连接确认码 123457
- 服务端收到后确认确认码,进入连接状态
四次挥手(挥手告别)
客户端和服务器端都可以主动发起断开请求
假如客户端先发起断开请求
- 首先客户端会向服务器端发送一个 FIN 包,此时会进入等待断开状态第一阶段,这是第一次握手
- 然后服务器端向客户端发送
ACK
确认包,确定要关闭的连接,对当前连接的状态进入CLOSE_WAIT 状态 (等待关闭连接的状态),这是第二次握手。(客户端接收到ACK
包后,进入等待断开状态的第二阶段,此时服务器端依然可以发送还没有发送完的数据,客户端还是可以接受数据,等待服务器端发送未发送完成的数据) - 当服务端发送完数据后,会给客户端发送一个FIN包,进入最后确认状态
LAST_ACK
,这是第三次握手 - 当客户端收到
FIN
确认后,会向客户端发送一个 ACK 包,确认关闭服务器与当前客户端的连接,这是第四次握手。(同时会进入超时等待状态(TIME_WAIT
),当超时时间过后,才会进入CLOSED
状态)
为什么需要超时等待状态(
TIME_WAIT
)?防止当客户端发送最后一次
ACK
包的时候,网络再次出现异常,导致服务端没有收到客户端最终确认的ACK
包,此时服务端会重发 FIN 包,客户端会相应这个FIN包,并重新发ACK
包+刷新超时时间
参考学习:
-
[再问我三次握手和四次挥手 ](https://zhuanlan.zhihu.com/p/86426969#:~:text=1. 三次握手. 三次握手(Three-way Handshake)其实就是指建立一个TCP连接时,需要客户端和服务器总共发送3个包。. 进行三次握手的主要作用就是为了确认双方的接收能力和发送能力是否正常、指定自己的初始化序列号为后面的可靠性传送做准备。. 实质上其实就是连接服务器指定端口,建立TCP连接,并同步连接双方的序列号和确认号,交换TCP窗口大小信息。. 刚开始客户端处于 Closed,进行三次握手:. 第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN©。. 此时客户端处于 SYN_SEND 状态。.)
评论区