建立连接——三次握手
要建立可靠的连接,有两个核心点要抓住
1️⃣ 连接🔗正确,即发送与接受都正常无误【SYN
的工作】
2️⃣ 信息正确✔️【ACK
的工作】
SYN
同步序列编号(Synchronize Sequence Numbers)是TCP/IP建立连接使用的握手信号。
ACK
确认字符(Acknowledgement)
三次握手的过程🔛
一次握手:客户端Client发送带有SYN
标志的数据包给服务端Server,客户端进入SYN_SEND
状态,等待服务端的确认。
⭕️ SYN
是为了建立并确认客户端Client
→
\rightarrow
→服务端Server的通信。
发送 | 接收 | 信息无误 | |
---|---|---|---|
客户端Client | ✔️ | ❌ | ❌ |
服务端Server | ❌ | ❌ | ❌ |
二次握手:服务端Server发送带有SYN
和ACK
标志的数据包给客户端Client,服务端进入SYN_RECV
状态
⭕️ ACK
是为了告诉客户端Client“接收到的信息正确”;SYN
是为了建立并确认服务端Server
→
\rightarrow
→客户端Client的通信。
发送 | 接收 | 信息无误 | |
---|---|---|---|
客户端Client | ✔️ | ✔️ | ✔️ |
服务端Server | ✔️ | ❌ | ❌ |
三次握手:客户端Client发送带有ACK
标志的数据包给服务端Server,此时客户端Client与服务端Server都进入ESTABLISHED
状态🔚
⭕️ ACK
是为了告诉服务端Server“接收到的信息正确”。
发送 | 接收 | 信息无误 | |
---|---|---|---|
客户端Client | ✔️ | ✔️ | ✔️ |
服务端Server | ✔️ | ✔️ | ✔️ |
❓为什么最后还要发送
ACK
确认?
防止已经失效的连接请求报文段,突然又传送到服务端Server从而产生错误。
(该连接请求报文段已经失去了时效性,可以理解他绕了老大一圈才到了Server,但是此时Client和Server已经两次握手了,连接正确✔【谈上了】,迟到的失效报文赶到也没用了呀!如果此时Server和Client已经断开连接了【分手】,姗姗来迟的失效报文会被Server以为Client又要建立连接【迟来的深情】,但是Client已经不会再理会Server的ACK
了!)
断开连接——四次挥手
MSL最长报文段寿命(Maximum Segment Lifetime):RFC 793建议设定为2min。
❓为什么不能把发送的
ACK
与FIN
合并起来?
因为服务器Server收到客户端Client断开连接的请求时,可能还有些数据没法完。【Server
→
\rightarrow
→ Client 还没断,服务端发啥,客户端接啥。】所以先回复ACK
,表示接收到了断开连接的请求,等到数据发完了,再发FIN
,断开数据传送。
❓如果第二次挥手的
ACK
没有送达客户端,会怎样?
客户端Client没收到ACK
,会重新发送FIN
❓为什么第四次挥手需要等待
2MSL
时间后才进入关闭CLOSE
状态?
1️⃣ 第四次挥手时,客户端Client发送给服务端Server的ACK
有可能丢失【服务端没收到客户端的确认,传输控制块TCB还没撤销,即连接🔗还没断完❗️】
如果服务端Server因为某些原因而没有收到ACK
的话,服务端Server会重新发送FIN
,如果客户端Client在2MSL的TIME_WAIT
时间等待状态内收到FIN
,就会重新发送ACK并且再次等待2MSL,防止服务端Server没有收到ACK
而不断重发FIN
。
2️⃣ 客户端Client在发送完最后一个ACK报文+2MSL时间等待状态后,本次连接时所产生的所有报文段都会从网络消失,避免了下一个新的连接中出现旧的连接请求报文段(无效报文段)。
⭕️注意看,服务端在接收到ACK
就立即进入CLOSED
关闭状态,而客户端Client发送完ACK
还等了2MSL时间,才进入CLOSED
状态,【B断开连接比A早】。