口试官,不要再问我三次握手和四次挥手

藏宝库编辑 2024-9-25 14:22:31 43 0 来自 中国
三次握手和四次挥手是各个公司常见的考点,也具有肯定的程度区分度,也被一些口试官作为热身题。很多小同伴说这个题目刚开始回复的挺好,但是反面越回复越冒冷汗,末了就歇菜了。
见过比较典范的口试场景是如许的:
       口试官:请先容下三次握手 求职者:第一次握手就是客户端给服务器端发送一个报文,第二次就是服务器收到报文之后,会应答一个报文给客户端,第三次握手就是客户端收到报文后再给服务器发送一个报文,三次握手就乐成了。口试官:然后呢?求职者:这就是三次握手的过程,很简朴的。口试官:。。。。。。(番外篇:一首凉凉送给你)
记取猿人谷一句话:口试时越简朴的题目,一般就是隐蔽着比较大的坑,一般都是需要将题目扩展的。上面求职者的回复不对吗?当然对,但隔断口试官的盼望可能尚有点隔断。
希望各人能带着如下题目举行阅读,收获会更大。
请画出三次握手和四次挥手的表现图
为什么毗连的时间是三次握手,关闭的时间却是四次握手?
什么是半毗连队列?
ISN(Initial Sequence Number)是固定的吗?
三次握手过程中可以携带数据吗?
如果第三次握手丢失了,客户端服务端会怎样处置惩罚?
SYN攻击是什么?
挥手为什么需要四次?
四次挥手开释毗连时,等候2MSL的意义?


1. 三次握手
三次握手(Three-way Handshake)着实就是指创建一个TCP毗连时,需要客户端和服务器统共发送3个包。举行三次握手的紧张作用就是为了确认两边的吸收本领和发送本领是否正常、指定自己的初始化序列号为反面的可靠性传送做准备。实质上着实就是毗连服务器指定端口,创建TCP毗连,并同步毗连两边的序列号和确认号,互换 TCP窗口巨细信息。
刚开始客户端处于 Closed 的状态,服务端处于 Listen 状态。举行三次握手:
第一次握手:客户端给服务端发一个 SYN 报文,并指明客户端的初始化序列号 ISN(c)。此时客户端处于 SYN_SEND 状态。
首部的同步位SYN=1,初始序号seq=x,SYN=1的报文段不能携带数据,但 要斲丧掉一个序号。
第二次握手:服务器收到客户端的 SYN 报文之后,会以自己的 SYN 报文作为应答,而且也是指定了自己的初始化序列号 ISN(s)。同时会把客户端的
ISN + 1 作为ACK 的值,表现自己已经收到了客户端的 SYN,此时服务器处于 SYN_REVD 的状态。
在确认报文段中SYN=1,ACK=1,确认号ack=x+1,初始序号seq=y。
第三次握手:客户端收到 SYN 报文之后,会发送一个 ACK 报文,当然,也是一样把服务器的 ISN + 1 作为 ACK 的值,表现已经收到了服务端的 SYN 报文,此时客户端处于 ESTABLISHED 状态。服务器收到 ACK 报文之后,也处于 ESTABLISHED 状态,此时,两边已创建起了毗连。
确认报文段ACK=1,确认号ack=y+1,序号seq=x+1(初始为seq=x,第二个报文段以是要+1),ACK报文段可以携带数据,不携带数据则不斲丧序号。
发送第一个SYN的一端将执行自动打开(active open),吸收这个SYN并发回下一个SYN的另一端执行被动打开(passive open)。
在socket编程中,客户端执行connect()时,将触发三次握手。


2.png 1.1 为什么需要三次握手,两次不可吗?
弄清这个题目,我们需要先弄明白三次握手的目标是什么,能不能只用两次握手来到达同样的目标。
第一次握手:客户端发送网络包,服务端收到了。如许服务端就能得出结论:客户端的发送本领、服务端的吸收本领是正常的。
第二次握手:服务端发包,客户端收到了。如许客户端就能得出结论:服务端的吸收、发送本领,客户端的吸收、发送本领是正常的。不外此时服务器并不能确认客户端的吸收本领是否正常。
第三次握手:客户端发包,服务端收到了。如许服务端就能得出结论:客户端的吸收、发送本领正常,服务器自己的发送、吸收本领也正常。
因此,需要三次握手才气确认两边的吸收与发送本领是否正常。
试想如果是用两次握手,则会出现下面这种环境:
如客户端发出毗连哀求,但因毗连哀求报文丢失而未收到确认,于是客户端再重传一次毗连哀求。后来收到了确认,创建了毗连。数据传输完毕后,就开释了毗连,客户端共发出了两个毗连哀求报文段,此中第一个丢失,第二个到达了服务端,但是第一个丢失的报文段只是在某些网络结点长时间滞留了,延误到毗连开释以后的某个时间才到达服务端,此时服务端误以为客户端又发出一次新的毗连哀求,于是就向客户端发出确认报文段,同意创建毗连,不接纳三次握手,只要服务端发出确认,就创建新的毗连了,此时客户端忽略服务端发来的确认,也不发送数据,则服务端同等等候客户端发送数据,浪费资源。
1.2 什么是半毗连队列?
服务器第一次收到客户端的 SYN 之后,就会处于 SYN_RCVD 状态,此时两边还没有完全创建其毗连,服务器会把此种状态下哀求毗连放在一个队列里,我们把这种队列称之为半毗连队列
当然尚有一个全毗连队列,就是已经完成三次握手,创建起毗连的就会放在全毗连队列中。如果队列满了就有可能会出现丢包征象。
这里在增补一点关于SYN-ACK 重传次数的题目:服务器发送完SYN-ACK包,如果未收到客户确认包,服务器举行首次重传,等候一段时间仍未收到客户确认包,举行第二次重传。如果重传次数高出体系规定的最大重传次数,体系将该毗连信息从半毗连队列中删除。注意,每次重传等候的时间不愿定雷同,一般会是指数增长,比方隔断时间为 1s,2s,4s,8s......
1.3 ISN(Initial Sequence Number)是固定的吗?
当一端为创建毗连而发送它的SYN时,它为毗连选择一个初始序号。ISN随时间而变革,因此每个毗连都将具有差别的ISN。ISN可以看作是一个32比特的计数器,每4ms加1 。如许选择序号的目标在于防止在网络中被延长的分组在以后又被传送,而导致某个毗连的一方对它做错误的表明。
三次握手的此中一个紧张功能是客户端和服务端互换 ISN(Initial Sequence Number),以便让对方知道接下来吸收数据的时间怎样按序列号组装数据。如果 ISN 是固定的,攻击者很轻易猜出后续的确认号,因此 ISN 是动态天生的。
1.4 三次握手过程中可以携带数据吗?
着实第三次握手的时间,是可以携带数据的。但是,第一次、第二次握手不可以携带数据
为什么如许呢?各人可以想一个题目,如果第一次握手可以携带数据的话,如果有人要恶意攻击服务器,那他每次都在第一次握手中的 SYN 报文中放入大量的数据。由于攻击者根本就不理服务器的吸收、发送本领是否正常,然后疯狂着重复发 SYN 报文的话,这会让服务器泯灭很多时间、内存空间来吸收这些报文。
也就是说,第一次握手不可以放数据,此中一个简朴的缘故因由就是会让服务器更加轻易受到攻击了。而对于第三次的话,此时客户端已经处于 ESTABLISHED 状态。对于客户端来说,他已经创建起毗连了,而且也已经知道服务器的吸收、发送本领是正常的了,以是能携带数据也没啥弊端。
1.5 SYN攻击是什么?
服务器端的资源分配是在二次握手时分配的,而客户端的资源是在完成三次握手时分配的,以是服务器轻易受到SYN洪泛攻击。SYN攻击就是Client在短时间内伪造大量不存在的IP地点,并向Server不停地发送SYN包,Server则复兴确认包,并等候Client确认,由于源地点不存在,因此Server需要不停重发直至超时,这些伪造的SYN包将长时间占用未毗连队列,导致正常的SYN哀求由于队列满而被抛弃,从而引起网络拥塞以致体系瘫痪。SYN 攻击是一种典范的 DoS/DDoS 攻击。
检测 SYN 攻击非常的方便,当你在服务器上看到大量的半毗连状态时,特殊是源IP地点是随机的,根本上可以断定这是一次SYN攻击。在 Linux/Unix 上可以利用体系自带的 netstats 命令来检测 SYN 攻击。
netstat-n -p TCP | grep SYN_RECV
常见的防御 SYN 攻击的方法有如下几种:
收缩超时(SYN Timeout)时间
增长最泰半毗连数
过滤网关防护
SYN cookies技能
2. 四次挥手
创建一个毗连需要三次握手,而制止一个毗连要颠末四次挥手(也有将四次挥手叫做四次握手的)。这由TCP的半关闭(half-close)造成的。所谓的半关闭,着实就是TCP提供了毗连的一端在竣事它的发送后还能吸收来自另一端数据的本领。
TCP 的毗连的拆除需要发送四个包,因此称为四次挥手(Four-way handshake),客户端或服务器均可自动发起挥手动作。
刚开始两边都处于 ESTABLISHED 状态,如果是客户端先发起关闭哀求。四次挥手的过程如下:
第一次挥手:客户端发送一个 FIN 报文,报文中会指定一个序列号。此时客户端处于 FIN_WAIT1 状态。
即发出毗连开释报文段(FIN=1,序号seq=u),并制止再发送数据,自动关闭TCP毗连,进入FIN_WAIT1(制止等候1)状态,等候服务端的确认。
第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序列号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。
即服务端收到毗连开释报文段后即发出确认报文段(ACK=1,确认号ack=u+1,序号seq=v),服务端进入CLOSEWAIT(关闭等候)状态,此时的TCP处于半关闭状态,客户端到服务端的毗连开释。客户端收到服务端的确认后,进入FINWAIT2(制止等候2)状态,等候服务端发出的毗连开释报文段。
第三次挥手:如果服务端也想断开毗连了,和客户端的第一次挥手一样,发给 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态。
即服务端没有要向客户端发出的数据,服务端发出毗连开释报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),服务端进入LAST_ACK(末了确认)状态,等候客户端的确认。
第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答,且把服务端的序列号值 +1 作为自己 ACK 报文的序列号值,此时客户端处于 TIME_WAIT 状态。需要过一阵子以确保服务端收到自己的 ACK 报文之后才会进入 CLOSED 状态,服务端收到 ACK 报文之后,就处于关闭毗连了,处于 CLOSED 状态。
即客户端收到服务端的毗连开释报文段后,对此发出确认报文段(ACK=1,seq=u+1,ack=w+1),客户端进入TIME_WAIT(时间等候)状态。此时TCP未开释掉,需要颠末期间等候计时器设置的时间2MSL后,客户端才进入CLOSED状态。
收到一个FIN只意味着在这一方向上没有数据活动。客户端执行自动关闭并进入TIMEWAIT是正常的,服务端通常执行被动关闭,不会进入TIMEWAIT状态。
在socket编程中,任何一方执行close()利用即可产生挥手利用。


3.png 2.1 挥手为什么需要四次?
由于当服务端收到客户端的SYN毗连哀求报文后,可以直接发送SYN+ACK报文。此中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭毗连时,当服务端收到FIN报文时,很可能并不会立刻关闭SOCKET,以是只能先复兴一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有比及我服务端全部的报文都发送完了,我才气发送FIN报文,因此不能一起发送。故需要四次挥手。
2.2 2MSL等候状态
TIME_WAIT状态也成为2MSL等候状态。每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime),它是任何报文段被抛弃前在网络内的最长时间。这个时间是有限的,由于TCP报文段以IP数据报在网络内传输,而IP数据报则有限制其生存时间的TTL字段。
对一个具体实现所给定的MSL值,处置惩罚的原则是:当TCP执行一个自动关闭,并发回末了一个ACK,该毗连必须在TIME_WAIT状态停顿的时间为2倍的MSL。如许可让TCP再次发送末了的ACK以防这个ACK丢失(另一端超时并重发末了的FIN)。
这种2MSL等候的另一个效果是这个TCP毗连在2MSL等候期间,界说这个毗连的插口(客户的IP地点和端标语,服务器的IP地点和端标语)不能再被利用。这个毗连只能在2MSL竣事后才气再被利用。
2.3 四次挥手开释毗连时,等候2MSL的意义?
MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,高出这个时间报文将被抛弃。
为了包管客户端发送的末了一个ACK报文段可以或许到达服务器。由于这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等候计时器。末了客户端和服务器都能正常的关闭。假设客户端不等候2MSL,而是在发送完ACK之后直接开释关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭毗连状态。
两个来由:
包管客户端发送的末了一个ACK报文段可以或许到达服务端。
这个ACK报文段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报文段的确认,服务端超时重传FIN+ACK报文段,而客户端能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重新启动2MSL计时器,末了客户端和服务端都进入到CLOSED状态,若客户端在TIME-WAIT状态不等候一段时间,而是发送完ACK报文段后立刻开释毗连,则无法收到服务端重传的FIN+ACK报文段,以是不会再发送一次确认报文段,则服务端无法正常进入到CLOSED状态。
防止“已失效的毗连哀求报文段”出现在本毗连中。
客户端在发送完末了一个ACK报文段后,再颠末2MSL,就可以使本毗连一连的时间内所产生的全部报文段都从网络中消散,使下一个新的毗连中不会出现这种旧的毗连哀求报文段。
2.4 为什么TIME_WAIT状态需要颠末2MSL才气返回到CLOSE状态?
理论上,四个报文都发送完毕,就可以直接进入CLOSE状态了,但是可能网络是不可靠的,有可能末了一个ACK丢失。以是TIME_WAIT状态就是用来重发可能丢失的ACK报文
3. 总结
《TCP/IP详解 卷1:协议》有一张TCP状态变迁图,很具有代表性,有助于各人理解三次握手和四次挥手的状态变革。如下图所示,粗的实线箭头表现正常的客户端状态变迁,粗的虚线箭头表现正常的服务器状态变迁。
以反口试官再问你三次握手和四次挥手,直接把这一篇文章丢给他就可以了,他想问的都在这里。
您需要登录后才可以回帖 登录 | 立即注册

Powered by CangBaoKu v1.0 小黑屋藏宝库It社区( 冀ICP备14008649号 )

GMT+8, 2024-10-18 20:27, Processed in 0.175783 second(s), 35 queries.© 2003-2025 cbk Team.

快速回复 返回顶部 返回列表