举个栗子:把客户端比作男孩 , 服务器比作女孩 。 通过他们的分手来说明“四次挥手”过程 。 \"第一次挥手\":日久见人心 , 男孩发现女孩变成了自己讨厌的样子 , 忍无可忍 , 于是决定分手 , 随即写了一封信告诉女孩 。 “第二次挥手”:女孩收到信之后 , 知道了男孩要和自己分手 , 怒火中烧 , 心中暗骂:你算什么东西 , 当初你可不是这个样子的!于是立马给男孩写了一封回信:分手就分手 , 给我点时间 , 我要把你的东西整理好 , 全部还给你! 男孩收到女孩的第一封信之后 , 明白了女孩知道自己要和她分手 。 随后等待女孩把自己的东西收拾好 。 “第三次挥手”:过了几天 , 女孩把男孩送的东西都整理好了 , 于是再次写信给男孩:你的东西我整理好了 , 快把它们拿走 , 从此你我恩断义绝!“第四次挥手”:男孩收到女孩第二封信之后 , 知道了女孩收拾好东西了 , 可以正式分手了 , 于是再次写信告诉女孩:我知道了 , 这就去拿回来!这里双方都有各自的坚持 。 女孩自发出第二封信开始 , 限定一天内收不到男孩回信 , 就会再发一封信催促男孩来取东西!男孩自发出第二封信开始 , 限定两天内没有再次收到女孩的信就认为 , 女孩收到了自己的第二封信;若两天内再次收到女孩的来信 , 就认为自己的第二封信女孩没收到 , 需要再写一封信 , 再等两天…..倘若双方信都能正常收到 , 最少只用四封信就能彻底分手!这就是“四次挥手” 。 4.为什么“握手”是三次 , “挥手”却要四次?TCP建立连接时之所以只需要\"三次握手\" , 是因为在第二次\"握手\"过程中 , 服务器端发送给客户端的TCP报文是以SYN与ACK作为标志位的 。 SYN是请求连接标志 , 表示服务器端同意建立连接;ACK是确认报文 , 表示告诉客户端 , 服务器端收到了它的请求报文 。 即SYN建立连接报文与ACK确认接收报文是在同一次\"握手\"当中传输的 , 所以\"三次握手\"不多也不少 , 正好让双方明确彼此信息互通 。 TCP释放连接时之所以需要“四次挥手”是因为FIN释放连接报文与ACK确认接收报文是分别由第二次和第三次\"握手\"传输的 。 为何建立连接时一起传输 , 释放连接时却要分开传输?建立连接时 , 被动方服务器端结束CLOSED阶段进入“握手”阶段并不需要任何准备 , 可以直接返回SYN和ACK报文 , 开始建立连接 。 释放连接时 , 被动方服务器 , 突然收到主动方客户端释放连接的请求时并不能立即释放连接 , 因为还有必要的数据需要处理 , 所以服务器先返回ACK确认收到报文 , 经过CLOSE-WAIT阶段准备好释放连接之后 , 才能返回FIN释放连接报文 。 所以是“三次握手” , “四次挥手” 。 5.为什么客户端在TIME-WAIT阶段要等2MSL?为的是确认服务器端是否收到客户端发出的ACK确认报文当客户端发出最后的ACK确认报文时 , 并不能确定服务器端能够收到该段报文 。 所以客户端在发送完ACK确认报文之后 , 会设置一个时长为2MSL的计时器 。 MSL指的是MaximumSegmentLifetime:一段TCP报文在传输过程中的最大生命周期 。 2MSL即是服务器端发出为FIN报文和客户端发出的ACK确认报文所能保持有效的最大时长 。 服务器端在1MSL内没有收到客户端发出的ACK确认报文 , 就会再次向客户端发出FIN报文;如果客户端在2MSL内 , 再次收到了来自服务器端的FIN报文 , 说明服务器端由于各种原因没有接收到客户端发出的ACK确认报文 。 客户端再次向服务器端发出ACK确认报文 , 计时器重置 , 重新开始2MSL的计时;否则客户端在2MSL内没有再次收到来自服务器端的FIN报文 , 说明服务器端正常接收了ACK确认报文 , 客户端可以进入CLOSED阶段 , 完成“四次挥手” 。 所以 , 客户端要经历时长为2SML的TIME-WAIT阶段;这也是为什么客户端比服务器端晚进入CLOSED阶段的原因6.抓包验证
推荐阅读