TCP
连接建立可以总结为三次握手
,TCP
连接释放可以总结为四次挥手
。
前言
- 客户端:主动发起请求的一端
- 服务端:被动连接的一端,服务启动后,处于
Listen
状态,如 nginx
服务器
TCP 连接建立后,服务端和客户端可以相互发送和接受数据。
TCP 一些单词缩写说明:
SYN: synchronize
表示同步序号,用来建立连接
ACK: Acknowledgment Number
SEQ: Sequence Number
PACK: packet
RST
连接复位请求
PSH
Push操作,在数据包到达接收端以后,立即传送给应用程序,而不是在缓冲区中排队
FIN
发送端已经达到数据末尾,双方的数据传送完成
Window
窗口大小,即滑动窗口,用来进行流量控制
三次握手
- 第一次握手:
客户端
向服务端
发送连接请求报文段,报文头:SYN=1,ACK=0,SEQ=x
。请求发送后,客户端便进入SYN-SENT
状态,其中
SYN=1,ACK=0
表示该报文为连接请求报文。其中 TCP 规定:SYN=1
的报文段不能有数据部分,但要消耗掉一个序号
SEQ=x
中 x
为本次TCP通信字节流
的初始序号
- 第二次握手:
服务端
收到连接请求报文后,如果同意连接,会发送一个应答:SYN=1,ACK=1,SEQ=y,PACK=x+1
。该应答发送完成后便进入 SYN-RCVD
状态
SYN=1,ACK=1
表示该报文为连接同意的应答报文
SEQ=y
表示服务端发送TCP通信字节流
的初始序号
PACK=x+1
表示服务端
希望下一个数据报发送序号(SEQ)从x+1
开始的字节
- 第三次握手:当
客户端
收到连接同意的应答后,还要向服务端
发送一个确认报文段。该报文段的头部为:ACK=1,SEQ=x+1,PACK=y+1
,其中
客户端
发完该报文段后进入 ESTABLISHED
状态
服务端
收到该应答后也进入 ESTABLISHED
状态
- 此时TCP连接建立完成,服务端和客户端可以可以开始数据传输
意义
- 保证连接可信建立
- 防止因通信问题导致建立失败
- 本质:
- 网络上的传输是没有连接的,包括TCP也是一样的
- TCP所谓的
连接
其实只不过是在通讯的双方维护一个 连接状态
,让它看上去好像有连接一样,如上面的 SYN
、ACK
四次挥手
连接断开时,可能是 客户端
或 服务端
发起,本示例以 客户端
发起连接断开为例:
- 第一次挥手:
客户端
认为数据发送完成,需要向 服务端
发送连接释放请求,该请求只有报文头,内容为 FIN=1,SEQ=x
,此时:客户端
将进入FIN-WAIT-1状态
FIN=1
表示该报文段是一个连接释放请求
SEQ=x
中 x-1
是 客户端
向 服务端
发送的最后一个字节的序号
- 第二次挥手:
服务端
收到连接释放请求后,会通知相应的 应用程序
连接已经释放。此时 服务端
进入 CLOSE-WAIT
状态,并向 客户端
发送连接释放的应答,其报文头包含:ACK=1,SEQ=y,PACK=x+1
,其中
ACK=1
表示应答(除TCP连接请求报文段外,TCP所有数据报中 ACK=1
均表示应答)
SEQ=y
中 y-1
是 服务端
向 客户端
发送的最后一个字节的序号
PACK=x+1
表示 服务端
已经成功接收了前 x
个字节,并希望下一个数据报发送序号(SEQ)从x+1
开始的字节
客户端
收到该应答,进入FIN-WAIT-2
状态,等待 服务端
发送连接释放请求
- 第二次挥手完成后,
客户端
到 服务端
方向的连接已经释放,服务端
不会再接收数据,客户端
也不会再发送数据。但 服务端
到 客户端
方向的连接仍然存在,服务端
可以继续向 客户端
发送数据
- 第三次挥手:当
服务端
向 客户端
发完所有数据后,向 客户端
发送连接释放请求,请求头:FIN=1,ACK=1,SEQ=y,PACK=x+1
,其中
- 第四次挥手:
客户端
收到释放请求后,向 服务端
发送确认应答
客户端
进入 TIME-WAIT
状态。该状态会持续2MSL时间,若该时间段内没有 服务端
的重发请求的话,就进入 CLOSED
状态
服务端
收到确认应答后,也进入 CLOSED
状态
至此,TCP
连接释放完成。