【计算机网络】TCP为什么需要4次挥手
TCP连接释放过程比较复杂。数据传输结束后,通信的双方都可释放连接。TCP连接释放过程是四次挥手。上篇中讲解了这四个字段的作用:因为在TCP释放连接,所以不需要用到同步位SYN字段,而要用到一个新的字段:FIN:终止位➢ 当终止位被置为1时,说明数据已发送完毕,请求释放连接。➢ 当终止位被置为0时,说明还有数据正在发送。A为客户端(Client),B为服务端(Server)在TCP释放连接的四次挥
计算机网络——TCP释放连接的4次挥手
TCP连接释放过程比较复杂。
数据传输结束后,通信的双方都可释放连接。
TCP连接释放过程是四次挥手。
TCP报文段首部
上篇中讲解了这四个字段的作用:
- s e q seq seq:序号
- a c k ack ack:确认号
- S Y N SYN SYN:同步位(释放连接不需要)
- A C K ACK ACK:确认位
因为在TCP释放连接,所以不需要用到同步位 S Y N SYN SYN 字段,而要用到一个新的字段:
-
F I N FIN FIN:终止位
➢ 当终止位被置为 1 1 1 时,说明数据已发送完毕,请求释放连接。
➢ 当终止位被置为 0 0 0 时,说明还有数据正在发送。
TCP建立连接
A A A 为客户端 ( C l i e n t ) (Client) (Client), B B B 为服务端 ( S e r v e r ) (Server) (Server)。
在TCP释放连接的四次挥手中,我们只需要关注这两个标志位: F I N 、 A C K FIN、ACK FIN、ACK
谁发出 F I N FIN FIN 的报文,就代表着它接下来不再发送任何数据,申请关闭连接通道。
而 A C K ACK ACK 报文就是一个回包的意思,用来确认对方发送连接的通道已经成功关闭了。
第一次挥手
假设本次TCP连接, A A A 先把数据发完了:
- 终止位 F I N = 1 FIN=1 FIN=1 被置为 1 1 1,表示我在发起释放连接的请求。
- 序号 s e q = u seq=u seq=u,我最后给你发的数据序号从 u u u 开始(只要发数据 就一定会有序号)
第二次挥手
B B B 同意了 A A A 的释放连接请求,所有数据都已接收完毕,此时会把服务端的接收缓存中剩下的所有数据都交给上层应用进程;
服务端
的接收窗口
、客户端
的发送窗口
此时都不需要了。
- B B B 收到了 A A A 发的请求,并回复确认号 a c k = u + 1 ack=u+1 ack=u+1。
- 有确认号,肯定有确认位 A C K = 1 ACK=1 ACK=1。
- 本次传输自己的序号 s e q = v seq=v seq=v。
此时,从 A A A 到 B B B 这个方向的连接就释放了,TCP连接处于半关闭状态。
B
B
B 若发送数据,
A
A
A 仍要接收,所以此时用到的是:服务端
的发送窗口
、客户端
的接受窗口
。
第三次挥手
第三次请求还是 B B B 向 A A A 发出的,在第二次请求与第三次请求中,这两个连续的请求包之间存在着隔断时间,因为对于 B B B 来说可能还有一些还未处理完的数据,此时需要一些异步等待时间;
我们抽象一下:
A:B啊,我不想玩了。
B:哦,你不想玩了啊,我知道了。
B:A啊,好吧,我也不玩了,拜拜。
A:好的,拜拜。
等服务端的数据都处理完成后,此时 B B B 给 A A A 发送的请求只是单纯确认的请求:
- 终止位 F I N = 1 FIN=1 FIN=1,表示我的数据全部处理完了,我也申请释放连接。
- 确认号 a c k = u + 1 ack=u+1 ack=u+1,表示你发送的 u + 1 u+1 u+1 之前的数据我全部收到了。
- 确认位 A C K = 1 ACK=1 ACK=1。
- 我本次请求的数据携带的序号字段为 s e q = w seq=w seq=w。
第四次挥手
A A A 收到了 B B B 的释放连接请求,并回复确认。
- 确认号 a c k = w + 1 ack=w+1 ack=w+1,表示你你发送的 w + 1 w+1 w+1 之前的数据我全部收到了。
- 确认位 A C K = 1 ACK=1 ACK=1。
- 自己本次数据的序号字段 s e q = u + 1 seq=u+1 seq=u+1 对应你上次请求的确认号。
至此, A A A 和 B B B 的连接释放完成。
四次挥手TCP连接的各个状态
- E S T A B − L I S H E D ESTAB-LISHED ESTAB−LISHED:已确认连接状态
- F I N − W A I T − 1 FIN-WAIT-1 FIN−WAIT−1:主动关闭方的第一个等待状态(此时在等待 B B B 的确认)
- F I N − W A I T − 2 FIN-WAIT-2 FIN−WAIT−2:主动关闭方的第二个等待状态(此时在等待 B B B 处理未处理完的一些资源)
- C L O S E − W A I T CLOSE-WAIT CLOSE−WAIT:半关闭状态(对于被动关闭方 B B B 可能还需要处理内部的一些资源)
- L A S T − A C K LAST-ACK LAST−ACK:等待最后一次确认状态
- T I M E − W A I T TIME-WAIT TIME−WAIT:等待计时状态(等待计时器)
- C L O S E D CLOSED CLOSED:关闭状态
一个 F I N FIN FIN 对应一个 A C K ACK ACK。
注意:只有主动关闭连接的,才有 T I M E − W A I T TIME-WAIT TIME−WAIT 状态。
TIME-WAIT状态解释
为什么会有这个状态(等待计时器)存在?
对于客户端 A A A 和服务端 B B B,都存在着一个超时计时器;
对于最后一次挥手, A A A 怎么知道 B B B 是否收到了呢?因为最后一次请求 B B B 不会给 A A A 回复,按以前的超时计时器来判断的话, A A A 会一直给 B B B 发 N N N 个请求,直到 B B B 给 A A A 回复确认请求,这显然是不可以的。
如果不设置超时计时器,万一对方真的没有收到呢?
所以此时就有一个 T I M E − W A I T TIME-WAIT TIME−WAIT(等待计时器)状态,为了确保我最后的一次请求 B B B 一定收到了。
假设我第四次请求丢失了,那么 B B B 的超时计时器发现后,会重新发送第三次请求,当 A A A 处在 T I M E − W A I T TIME-WAIT TIME−WAIT 状态时,又收到了第三次请求,则证明我发送的第四次请求丢失了, B B B 没有收到,此时 A A A 会重新发送第四次请求。
这样双方就都可以判断最后一次挥手有没有完成,判断依据是:在这 2 M S L 2MSL 2MSL 的等待时间中,对方都没有再给我发任何重复的数据包过来,那么我就可以认为对方收到了最后一次请求。
M S L ( M a x i m u m S e g m e n t L i f e t i m e ) MSL(Maximum\ Segment\ Lifetime) MSL(Maximum Segment Lifetime) 是报文最大生存时间
A A A 必须等待 2 M S L 2MSL 2MSL 的时间:
-
第一,为了保证 A A A 发送的最后一个 A C K ACK ACK 报文段能够到达 B B B。
-
第二,防止 “已失效的连接请求报文段” 出现在本连接中。
A A A 在发送完最后一个 A C K ACK ACK 报文段后,再经过时间 2 M S L 2MSL 2MSL,就可以使本连接持续的时间内产生的所有报文段,都从网络中消失。
这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
更详细的分析可参考小林coding的TCP面试题
TIME_WAIT 过多有什么危害?如何优化 TIME_WAIT?
还是挺详细的。
更多推荐
所有评论(0)