A 客户端,B 服务端
三次握手
- 第一次握手:客户端发送网络包,服务端收到网络包,服务端就能得出结论:客户端的发送能力以及服务端的接受能力是正常的
- 第二次握手:服务端发包,客户端收到,客户端明白:自己和服务端的接受与发送能力都没问题,但此时服务端并不能确定客户端的接受能力是否正常
- 第三次握手:客户端发送,服务端收到,此时两者都知道双方都没问题
三次握手的状态变化
- 第一次握手:客户端给服务端发送一个 SYN 报文,并指明自己的初始化序列号 ISN(c)。 此时客户端处于 SYN_Send 状态
- 第二层握手:服务端收到 SYN 报文,会以自己的 SYN 报文作为应答,并且指定自己的初始化序列号 ISN(s), 同时会把客户端的 INS + 1 作为 ACK 的值,表示自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态
- 第三次握手:客户端收到 SYN 报文后,回一个 ACK 报文,同样把服务器的 ISN + 1 作为 ACK 的值,表示收到了 SYN 报文,此时客户端处于 establised 状态
- 服务端收到 ACK 后,也同样处于 establised 状态, 此时双方建立了链接
三次我握手的作用
- 确认双方的接受发送能力是否正常
- 指定自己的初始序列号,为后面的可靠传输做准备
ISN 是固定的吗
不是,是动态生成的,以此来防止攻击者轻易的猜出后续的确认号
第三次握手可以携带数据,因为客户端已经明白双方的接收能力没有问题
四次挥手
- 第一次挥手:客户端发送 FIN 报文,报文会指定一个序列号,此时客户端处于 FIN_WAIT1 状态
- 第二次挥手:服务端收到 FIN 报文后,发送一个 ACK 报文,且把服务端的序列号 + 1 作为 ACK 报文的序列号值,表明自己收到了客户端的报文,此时服务端处于 CLOSE_WAIT 状态。
- 第三次挥手:如果服务端也想断开链接,和客户端第一次挥手一样,发送 FIN 报文,且指定一个序列号,此时服务端处于 LAST_ACK 状态。
- 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 作为应答,同样是把服务端的序列号 + 1 作为自己 ACK 报文的序列号,此时客户端处于 TIME_WAIT 状态,需要过一阵子确保服务端收到自己的 ACK 报文后才会进入 CLOSED 状态
- 服务端收到 ACK 报文之后,就处于关闭状态了,处于 CLOSED 状态
至于第四步如何知道服务端收到自己的 ACK 呢,因为如果服务端没有收到 ACK 服务端会重发 FIN 报文,如果客户端再次收到了 FIN 报文,自然就知道自己的 ACK 丢失了,则会再次发送 ACK