以下内容来自于小码哥"网络协议从入门到底层原理"
TCP
-释放连接-4
次挥手
image.png
-
FIN-WAIT-1
: 表示想主动关闭连接
-- 向对方发送了FIN
报文, 此时进入到FIN-WAIT-1
状态 -
CLOSE-WAIT
: 表示在等待关闭
-- 当对方发送FIN
给自己, 自己会回应一个ACK
报文给对方, 此时则进入到CLOSE-WAIT
状态
-- 在此状态下, 需要考虑自己是否还有数据要发送给对方, 如果没有, 发送FIN
报文给对方 -
FIN-WAIT-2
: 只要对方发送ACK
确认后, 主动方就会处于FIN-WAIT-2
状态, 然后等待对方发送FIN
报文 -
CLOSING
: 一种比较罕见的例外状态
-- 表示你发送FIN
报文后, 并没有收到对方的ACK
报文, 反而却也收到了对方的FIN
报文
-- 如果双方几乎在同时准备关闭连接的话, 那么就出现了双方同时发送FIN
报文的情况, 也即会出现CLOSING
状态
-- 表示双方都正在关闭连接 -
LAST-ACK
: 被动关闭的一方在发送FIN
报文之后, 最后等待对方的ACK
报文
-- 当收到ACK
报文后, 即可进入CLOSED
状态了 -
TIME-WAIT
: 表示收到了对方的FIN
报文, 并发送出了ACK
报文, 就等2MSL
后即可进入CLOSED
状态了
-- 如果FIN-WAIT-1
状态下, 收到了对方同时带FIN
标志和ACK
标志的报文时
✅可以直接进入到TIME-WAIT
状态, 而无须经过FIN-WAIT-2
状态 -
CLOSED
: 关闭状态 -
由于有些状态的时间比较短暂, 所以很难用
netstat
命令看到, 比如SYN-RCVD
、FIN-WAIT-1
等
TCP
-释放连接-细节
-
TCP/IP
协议栈在设计上, 允许任何一方先发起断开请求. 这里演示的是client
主动要求断开 -
client
发送ACK
后, 需要有个TIME-WAIT
阶段, 等待一段时间后, 再真正关闭连接
-- 一般是等待2
倍的MSL(Maximum Segment Lifetime)最大分段生存期
✅MSL
是TCP
报文在Internet
上的最长生存时间
✅每个具体的TCP
实现都必须选择一个确定的MSL
值,RFC 1122
建议是2
分钟
✅可以防止本次连接中产生的数据包误传到下一次连接中(因为本次连接中的数据包都会在2MSL
时间内消失了) -
如果
client
发送ACK
后马上释放了, 然后又因为网络原因,server
没有收到client
的ACK
,server
就会重发FIN
-- 这时可能出现的情况是:
①client
没有任何响应, 服务器那边会干等, 甚至多次重发FIN
, 浪费资源
②client
有个新的应用程序刚好分配了同一个端口号, 新的应用程序收到FIN
后马上执行断开连接的操作, 本来它可能是想跟server
建立连接的
TCP
-释放连接-疑问
-
为什么释放连接的时候, 要进行
4
次挥手?
--TCP
是全双工模式
-- 第1
次挥手: 当主机1
发出FIN
报文段时
✅表示主机1
告诉主机2
,主机1
已经没有数据要发送了, 但是, 此时主机1
还是可以接受来自主机2
的数据 -
第
2
次挥手: 当主机2
返回ACK
报文段时
✅表示主机2
已经知道主机1
没有数据发送了, 但是主机2
还是可以发送数据到主机1
的 -
第
3
次挥手: 当主机2
也发送了FIN
报文段时
✅表示主机2
告诉主机1
,主机2
已经没有数据要发送了 -
第
4
次挥手: 当主机1
返回ACK
报文段时
✅表示主机1
已经知道主机2
没有数据发送了. 随后正式断开整个TCP
连接
TCP
-释放连接-抓包
-
有时候在使用抓包工具的时候, 有可能只会看到"
3
次"挥手
-- 这其实是将第2
,3
次挥手合并了 -
当
server
接收到client
的FIN
时, 如果server
后面也没有数据要发送给client
了
-- 这时,server
就可以将第2
,3
次挥手合并, 同时告诉client
两件事
✅已经知道client
没有数据要发
✅server
已经没有数据要发了
网友评论