TCP 三次握手、四次挥手
常见的 TCP 中的头部数据表示
-
ACK:该位为
1
时,「确认应答」的字段变为有效,TCP 规定除了最初建立连接时的SYN
包之外该位必须设置为1
用来解决丢包的问题。
-
SYN:该位为
1
时,表示希望建立连接,并在其「序列号」的字段进行序列号初始值的设定用来解决网络包乱序问题。
-
RST:该位为
1
时,表示 TCP 连接中出现异常必须强制断开连接 -
FIN:该位为
1
时,表示今后不会再有数据发送,希望断开连接。当通信结束希望断开连接时,通信双方的主机之间就可以相互交换FIN
位为 1 的 TCP 段
TCP 三次握手
一开始,客户端和服务端都处于
CLOSED
状态。先是服务端主动监听某个端口,处于LISTEN
状态
- 第一个报文—— SYN 报文
- 客户端会随机初始化序号(
client_isn
),将此序号置于 TCP 首部的「序号」字段中,同时把SYN
标志位置为1
,表示SYN
报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于SYN-SENT
状态。
- 客户端会随机初始化序号(
- 第二个报文 —— SYN + ACK 报文
- 服务端收到客户端的
SYN
报文后,首先服务端也随机初始化自己的序号(server_isn
),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入client_isn + 1
, 接着把SYN
和ACK
标志位置为1
。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于SYN-RCVD
状态。
- 服务端收到客户端的
- 第三个报文 —— ACK 报文
- 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部
ACK
标志位置为1
,其次「确认应答号」字段填入server_isn + 1
,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于ESTABLISHED
状态。
- 客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部
服务器收到客户端的应答报文后,也进入 ESTABLISHED
状态,此时 TCP 建立结束,双方可以收发数据。
为什么是三次握手?不是两次、四次?
- 三次握手才能保证双方具有接收和发送的能力
- 三次握手才可以阻止重复历史连接的初始化
- 三次握手才可以同步双方的初始序列号
- 三次握手才可以避免资源浪费
TCP 四次挥手过程
客户端主动关闭连接 —— TCP 四次挥手
- 客户端打算关闭连接,此时会发送一个 TCP 首部
FIN
标志位被置为1
的报文,也即FIN
报文,之后客户端进入FIN_WAIT_1
状态。 - 服务端收到该报文后,就向客户端发送
ACK
应答报文,接着服务端进入CLOSED_WAIT
状态。 - 客户端收到服务端的
ACK
应答报文后,之后进入FIN_WAIT_2
状态。 - 等待服务端处理完数据后,也向客户端发送
FIN
报文,之后服务端进入LAST_ACK
状态。 - 客户端收到服务端的
FIN
报文后,回一个ACK
应答报文,之后进入TIME_WAIT
状态 - 服务器收到了
ACK
应答报文后,就进入了CLOSED
状态,至此服务端已经完成连接的关闭。 - 客户端在经过
2MSL
一段时间后,自动进入CLOSED
状态,至此客户端也完成连接的关闭。
客户端和服务端都需要一个 FIN 和一个 ACK,因此通常被称为四次挥手。
这里一点需要注意是:主动关闭连接的,才有 TIME_WAIT 状态。
为什么挥手需要四次?
回顾上方四次挥手双方发 FIN
包的过程,就能理解为什么需要四次了。
- 关闭连接时,客户端向服务端发送
FIN
时,仅仅表示客户端不再发送数据了但是还能接收数据。 - 服务器收到客户端的
FIN
报文时,先回一个ACK
应答报文,而服务端可能还有数据需要处理和发送,等服务端不再发送数据时,才发送FIN
报文给客户端来表示同意现在关闭连接。
从上面过程可知,服务端通常需要等待完成数据的发送和处理,所以服务端的 ACK
和 FIN
一般都会分开发送,从而比三次握手导致多了一次。
引用文章:
https://www.cnblogs.com/xiaolincoding/p/12638546.html
补充:
1、为什么需要 TCP 协议? TCP 工作在哪一层?
IP
层是「不可靠」的,它不保证网络包的交付、不保证网络包的按序交付、也不保证网络包中的数据的完整性。
如果需要保障网络数据包的可靠性,那么就需要由上层(传输层)的 TCP
协议来负责。
因为 TCP 是一个工作在传输层的可靠数据传输的服务,它能确保接收端接收的网络包是无损坏、无间隔、非冗余和按序的。
2、标志位
TCP的常用标志位的分别代表:
SYN(synchronous建立联机)
ACK(acknowledgement 确认)
PSH(push传送)
FIN(finish结束)
RST(reset重置)
URG(urgent紧急)
Sequence number(顺序号码)
Acknowledge number(确认号码)
总结:其实为了能快速安全的链接或者关闭,建链中的这些syn,fin等都是相互约定的一些交互状态码,外加一些随机数,相互叠加校验,数据都不会太长,也不会有多复杂。