中年三次握手和四次挥手说完了,还让我手动写个HTTP协议代码( 二 )


发送完毕后 , 客户端进入 SYN_SEND 状态 。
(2) 第二次握手(SYN=1, ACK=1, seq=y, ACKnum=x+1):
服务器发回确认包(ACK)应答 。 即 SYN 标志位和 ACK 标志位均为1 。 服务器端选择自己 ISN 序列号 , 放到 Seq 域里 , 同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1 , 即X+1 。 发送完毕后 , 服务器端进入 SYN_RCVD 状态 。
(3) 第三次握手(ACK=1 , ACKnum=y+1)
客户端再次发送确认包(ACK) , SYN 标志位为0 , ACK 标志位为1 , 并且把服务器发来 ACK 的序号字段+1 , 放在确定字段中发送给对方 , 并且在数据段放写ISN的+1
发送完毕后 , 客户端进入 ESTABLISHED 状态 , 当服务器端接收到这个包时 , 也进入 ESTABLISHED 状态 , TCP 握手结束 。
你如果这么说 , 面试官有可能还会问 , 你这也太官方了 , 能不能说说你的理解 , 那么你可以用一个实际上的例子来给他说一下 ,
LZ:鸡丁 , 嘿 , 我是XX , 你听的到我说话么?
鸡丁:吵吵啥 , 听到了 , 除了你我还能认识谁 。
LZ:你听的到你还不赶紧回复 , 怪不得你没有女朋友呢 。 那我们再继续交流一下吧 。
而这三次的对话过程就是通俗的三次握手 , 期间对话三次 , 以此来确定两个方向上的数据传输通道是否正常 。
四次挥手
中年三次握手和四次挥手说完了,还让我手动写个HTTP协议代码
本文插图
那么四次挥手怎么来回答呢?
(1)第一次挥手(FIN=1 , seq=x)
假设客户端想要关闭连接 , 客户端发送一个 FIN 标志位置为1的包 , 表示自己已经没有数据可以发送了 , 但是仍然可以接受数据 。
发送完毕后 , 客户端进入 FIN_WAIT_1 状态 。
(2) 第二次挥手(ACK=1 , ACKnum=x+1)
服务器端确认客户端的 FIN 包 , 发送一个确认包 , 表明自己接受到了客户端关闭连接的请求 , 但还没有准备好关闭连接 。
发送完毕后 , 服务器端进入 CLOSE_WAIT 状态 , 客户端接收到这个确认包之后 , 进入 FIN_WAIT_2 状态 , 等待服务器端关闭连接 。
(3) 第三次挥手(FIN=1 , seq=y)
服务器端准备好关闭连接时 , 向客户端发送结束连接请求 , FIN 置为1 。
发送完毕后 , 服务器端进入 LAST_ACK 状态 , 等待来自客户端的最后一个ACK 。
(4) 第四次挥手(ACK=1 , ACKnum=y+1)
客户端接收到来自服务器端的关闭请求 , 发送一个确认包 , 并进入 TIME_WAIT状态 , 等待可能出现的要求重传的 ACK 包 。
服务器端接收到这个确认包之后 , 关闭连接 , 进入 CLOSED 状态 。
客户端等待了某个固定时间(两个最大段生命周期 , 2MSL , 2 Maximum Segment Lifetime)之后 , 没有收到服务器端的 ACK, 认为服务器端已经正常关闭连接 , 于是自己也关闭连接 , 进入 CLOSED 状态 。 两次后会重传直到超时 。 如果多了会有大量半链接阻塞队列 。
那么怎么去通俗的给面试官说呢?
【中年三次握手和四次挥手说完了,还让我手动写个HTTP协议代码】LZ:鸡丁呀 , 我要说的都说完了 , 你还有啥事么?
鸡丁:你说的我都明白了 , 但是别断 , 我还有要嘱咐你的 , 给我找女朋友的事情 。
鸡丁:xxxxx , 我说完了 。
XX , 行啦 , 别BB了 , 记住了 , 挂了吧 。
如果面试官问你的时候 , 你这么回答的话 , 既有官方的解释 , 还有本身自己的理解 , 那么这个问题就已经算是差不多了 ,
而面试官显然不可能会这么放过你 , 肯定再给你来个雷 , 为啥是三次握手 , 而是四次挥手呢?为啥不是三次呢?
这是因为服务端在LISTEN状态下 , 收到建立连接请求的SYN报文后 , 把ACK和SYN放在一个报文里发送给客户端 。 而关闭连接时 , 当收到对方的FIN报文时 , 仅仅表示对方不再发送数据了但是还能接收数据 , 己方是否现在关闭发送数据通道 , 需要上层应用来决定 , 因此 , 己方ACK和FIN一般都会分开发送 。 所以这时候挥手的时候就是四次 , 而不再是三次了 。


推荐阅读