详解三次握⼿和四次挥⼿
三次握⼿和四次挥⼿是各个公司常见的考点,也具有⼀定的⽔平区分度,也被⼀些⾯试官作为热⾝题。很多⼩伙伴说这个问题刚开始回答的
挺好,但是后⾯越回答越冒冷汗,最后就歇菜了。
见过⽐较典型的⾯试场景是这样的:
⾯试官:请介绍下三次握⼿
求职者:第⼀次握⼿就是客户端给服务器端发送⼀个报⽂,第⼆次就是服务器收到报⽂之后,会应答⼀个报⽂给客户端,第三次握⼿
就是客户端收到报⽂后再给服务器发送⼀个报⽂,三次握⼿就成功了。
⾯试官:然后呢?
求职者:这就是三次握⼿的过程,很简单的。
⾯试官:。。。。。。
(番外篇:⼀⾸凉凉送给你)
记住猿⼈⾕⼀句话:⾯试时越简单的问题,⼀般就是隐藏着⽐较⼤的坑,⼀般都是需要将问题扩展的。上⾯求职者的回答不对吗?当然对,
但距离⾯试官的期望可能还有点距离。
希望⼤家能带着如下问题进⾏阅读,收获会更⼤。
1.请画出三次握⼿和四次挥⼿的⽰意图
2.为什么连接的时候是三次握⼿?
3.什么是半连接队列?
(InitialSequenceNumber)是固定的吗?
5.三次握⼿过程中可以携带数据吗?
6.如果第三次握⼿丢失了,客户端服务端会如何处理?
攻击是什么?
8.挥⼿为什么需要四次?
9.四次挥⼿释放连接时,等待2MSL的意义?
1.三次握⼿
三次握⼿(Three-wayHandshake)其实就是指建⽴⼀个TCP连接时,需要客户端和服务器总共发送3个包。进⾏三次握⼿的主要作⽤就
是为了确认双⽅的接收能⼒和发送能⼒是否正常、指定⾃⼰的初始化序列号为后⾯的可靠性传送做准备。实质上其实就是连接服务器指定端
⼝,建⽴TCP连接,并同步连接双⽅的序列号和确认号,交换TCP窗⼝⼤⼩信息。
刚开始客户端处于Clod的状态,服务端处于Listen状态。
进⾏三次握⼿:
第⼀次握⼿:客户端给服务端发⼀个SYN报⽂,并指明客户端的初始化序列号ISN。此时客户端处于SYN_SENT状态。
⾸部的同步位SYN=1,初始序号q=x,SYN=1的报⽂段不能携带数据,但要消耗掉⼀个序号。
第⼆次握⼿:服务器收到客户端的SYN报⽂之后,会以⾃⼰的SYN报⽂作为应答,并且也是指定了⾃⼰的初始化序列号ISN(s)。同
时会把客户端的ISN+1作为ACK的值,表⽰⾃⼰已经收到了客户端的SYN,此时服务器处于SYN_RCVD的状态。
在确认报⽂段中SYN=1,ACK=1,确认号ack=x+1,初始序号q=y。
第三次握⼿:客户端收到SYN报⽂之后,会发送⼀个ACK报⽂,当然,也是⼀样把服务器的ISN+1作为ACK的值,表⽰已经收
到了服务端的SYN报⽂,此时客户端处于ESTABLISHED状态。服务器收到ACK报⽂之后,也处于ESTABLISHED状态,此时,双
⽅已建⽴起了连接。
确认报⽂段ACK=1,确认号ack=y+1,序号q=x+1(初始为q=x,第⼆个报⽂段所以要+1),ACK报⽂段可以携带数据,不携
带数据则不消耗序号。
发送第⼀个SYN的⼀端将执⾏主动打开(activeopen),接收这个SYN并发回下⼀个SYN的另⼀端执⾏被动打开(passiveopen)。
在socket编程中,客户端执⾏connect()时,将触发三次握⼿。
1.1为什么需要三次握⼿,两次不⾏吗?
弄清这个问题,我们需要先弄明⽩三次握⼿的⽬的是什么,能不能只⽤两次握⼿来达到同样的⽬的。
第⼀次握⼿:客户端发送⽹络包,服务端收到了。
这样服务端就能得出结论:客户端的发送能⼒、服务端的接收能⼒是正常的。
第⼆次握⼿:服务端发包,客户端收到了。
这样客户端就能得出结论:服务端的接收、发送能⼒,客户端的接收、发送能⼒是正常的。不过此时服务器并不能确认客户端的接收能
⼒是否正常。
第三次握⼿:客户端发包,服务端收到了。
这样服务端就能得出结论:客户端的接收、发送能⼒正常,服务器⾃⼰的发送、接收能⼒也正常。
因此,需要三次握⼿才能确认双⽅的接收与发送能⼒是否正常。
试想如果是⽤两次握⼿,则会出现下⾯这种情况:
如客户端发出连接请求,但因连接请求报⽂丢失⽽未收到确认,于是客户端再重传⼀次连接请求。后来收到了确认,建⽴了连接。数
据传输完毕后,就释放了连接,客户端共发出了两个连接请求报⽂段,其中第⼀个丢失,第⼆个到达了服务端,但是第⼀个丢失的报
⽂段只是在某些⽹络结点长时间滞留了,延误到连接释放以后的某个时间才到达服务端,此时服务端误认为客户端⼜发出⼀次新的连
接请求,于是就向客户端发出确认报⽂段,同意建⽴连接,不采⽤三次握⼿,只要服务端发出确认,就建⽴新的连接了,此时客户端
忽略服务端发来的确认,也不发送数据,则服务端⼀致等待客户端发送数据,浪费资源。
1.2什么是半连接队列?
服务器第⼀次收到客户端的SYN之后,就会处于SYN_RCVD状态,此时双⽅还没有完全建⽴其连接,服务器会把此种状态下请求连接放
在⼀个队列⾥,我们把这种队列称之为半连接队列。
当然还有⼀个全连接队列,就是已经完成三次握⼿,建⽴起连接的就会放在全连接队列中。如果队列满了就有可能会出现丢包现象。
这⾥在补充⼀点关于SYN-ACK重传次数的问题:
服务器发送完SYN-ACK包,如果未收到客户确认包,服务器进⾏⾸次重传,等待⼀段时间仍未收到客户确认包,进⾏第⼆次重传。如果重
传次数超过系统规定的最⼤重传次数,系统将该连接信息从半连接队列中删除。
注意,每次重传等待的时间不⼀定相同,⼀般会是指数增长,例如间隔时间为1s,2s,4s,8s…
1.3ISN(InitialSequenceNumber)是固定的吗?
当⼀端为建⽴连接⽽发送它的SYN时,它为连接选择⼀个初始序号。ISN随时间⽽变化,因此每个连接都将具有不同的ISN。ISN可以看作是
⼀个32⽐特的计数器,每4ms加1。这样选择序号的⽬的在于防⽌在⽹络中被延迟的分组在以后⼜被传送,⽽导致某个连接的⼀⽅对它做
错误的解释。
三次握⼿的其中⼀个重要功能是客户端和服务端交换ISN(InitialSequenceNumber),以便让对⽅知道接下来接收数据的时候如何按序列
号组装数据。如果ISN是固定的,攻击者很容易猜出后续的确认号,因此ISN是动态⽣成的。
1.4三次握⼿过程中可以携带数据吗?
其实第三次握⼿的时候,是可以携带数据的。但是,第⼀次、第⼆次握⼿不可以携带数据
为什么这样呢?⼤家可以想⼀个问题,假如第⼀次握⼿可以携带数据的话,如果有⼈要恶意攻击服务器,那他每次都在第⼀次握⼿中的SYN
报⽂中放⼊⼤量的数据。因为攻击者根本就不理服务器的接收、发送能⼒是否正常,然后疯狂着重复发SYN报⽂的话,这会让服务器花费
很多时间、内存空间来接收这些报⽂。
也就是说,第⼀次握⼿不可以放数据,其中⼀个简单的原因就是会让服务器更加容易受到攻击了。⽽对于第三次的话,此时客户端已经处于
ESTABLISHED状态。对于客户端来说,他已经建⽴起连接了,并且也已经知道服务器的接收、发送能⼒是正常的了,所以能携带数据也
没啥⽑病。
1.5SYN攻击是什么?
服务器端的资源分配是在⼆次握⼿时分配的,⽽客户端的资源是在完成三次握⼿时分配的,所以服务器容易受到SYN洪泛攻击。SYN攻击就
是Client在短时间内伪造⼤量不存在的IP地址,并向Server不断地发送SYN包,Server则回复确认包,并等待Client确认,由于源地址不存
在,因此Server需要不断重发直⾄超时,这些伪造的SYN包将长时间占⽤未连接队列,导致正常的SYN请求因为队列满⽽被丢弃,从⽽引
起⽹络拥塞甚⾄系统瘫痪。SYN攻击是⼀种典型的DoS/DDoS攻击。
检测SYN攻击⾮常的⽅便,当你在服务器上看到⼤量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是⼀次SYN攻击。在
Linux/Unix上可以使⽤系统⾃带的netstat命令来检测SYN攻击。
常见的防御SYN攻击的⽅法有如下⼏种:
netstat-n-pTCP|grepSYN_RECV1
缩短超时(SYNTimeout)时间
增加最⼤半连接数
过滤⽹关防护
SYNcookies技术
2.四次挥⼿
建⽴⼀个连接需要三次握⼿,⽽终⽌⼀个连接要经过四次挥⼿(也有将四次挥⼿叫做四次握⼿的)。这由TCP的半关闭(half-clo)造成
的。所谓的半关闭,其实就是TCP提供了连接的⼀端在结束它的发送后还能接收来⾃另⼀端数据的能⼒。
TCP连接的拆除需要发送四个包,因此称为四次挥⼿(Four-wayhandshake),客户端或服务端均可主动发起挥⼿动作。
刚开始双⽅都处于ESTABLISHED状态,假如是客户端先发起关闭请求。四次挥⼿的过程如下:
第⼀次挥⼿:客户端发送⼀个FIN报⽂,报⽂中会指定⼀个序列号。此时客户端处于FIN_WAIT1状态。
即发出连接释放报⽂段(FIN=1,序号q=u),并停⽌再发送数据,主动关闭TCP连接,进⼊FIN_WAIT1(终⽌等待1)状态,等待
服务端的确认。
第⼆次挥⼿:服务端收到FIN之后,会发送ACK报⽂,且把客户端的序列号值+1作为ACK报⽂的序列号值,表明已经收到客户端
的报⽂了,此时服务端处于CLOSE_WAIT状态。
即服务端收到连接释放报⽂段后即发出确认报⽂段(ACK=1,确认号ack=u+1,序号q=v),服务端进⼊CLOSE_WAIT(关闭等
待)状态,此时的TCP处于半关闭状态,客户端到服务端的连接释放。客户端收到服务端的确认后,进⼊FIN_WAIT2(终⽌等待2)状
态,等待服务端发出的连接释放报⽂段。
第三次挥⼿:如果服务端也想断开连接了,和客户端的第⼀次挥⼿⼀样,发给FIN报⽂,且指定⼀个序列号。此时服务端处于
LAST_ACK的状态。
即服务端没有要向客户端发出的数据,服务端发出连接释放报⽂段(FIN=1,ACK=1,序号q=w,确认号ack=u+1),服务端进⼊
LAST_ACK(最后确认)状态,等待客户端的确认。
第四次挥⼿:客户端收到FIN之后,⼀样发送⼀个ACK报⽂作为应答,且把服务端的序列号值+1作为⾃⼰ACK报⽂的序列号值,
此时客户端处于TIME_WAIT状态。需要过⼀阵⼦以确保服务端收到⾃⼰的ACK报⽂之后才会进⼊CLOSED状态,服务端收到ACK
报⽂之后,就处于关闭连接了,处于CLOSED状态。
即客户端收到服务端的连接释放报⽂段后,对此发出确认报⽂段(ACK=1,q=u+1,ack=w+1),客户端进⼊TIME_WAIT(时间
等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,客户端才进⼊CLOSED状态。
收到⼀个FIN只意味着在这⼀⽅向上没有数据流动。客户端执⾏主动关闭并进⼊TIME_WAIT是正常的,服务端通常执⾏被动关闭,不会进⼊
TIME_WAIT状态。
在socket编程中,任何⼀⽅执⾏clo()操作即可产⽣挥⼿操作。
2.1挥⼿为什么需要四次?
因为当服务端收到客户端的SYN连接请求报⽂后,可以直接发送SYN+ACK报⽂。其中ACK报⽂是⽤来应答的,SYN报⽂是⽤来同步的。
但是关闭连接时,当服务端收到FIN报⽂时,很可能并不会⽴即关闭SOCKET,所以只能先回复⼀个ACK报⽂,告诉客户端,“你发的FIN
报⽂我收到了”。只有等到我服务端所有的报⽂都发送完了,我才能发送FIN报⽂,因此不能⼀起发送。故需要四次挥⼿。
2.22MSL等待状态
TIME_WAIT状态也成为2MSL等待状态。每个具体TCP实现必须选择⼀个报⽂段最⼤⽣存时间MSL(MaximumSegmentLifetime),
它是任何报⽂段被丢弃前在⽹络内的最长时间。这个时间是有限的,因为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是MaximumSegmentLifetime的英⽂缩写,可译为“最长报⽂段寿命”,它是任何报⽂在⽹络上存在的最长时间,超过这个
时间报⽂将被丢弃。
为了保证客户端发送的最后⼀个ACK报⽂段能够到达服务器。因为这个ACK有可能丢失,从⽽导致处在LAST-ACK状态的服务器收不到对
FIN-ACK的确认报⽂。服务器会超时重传这个FIN-ACK,接着客户端再重传⼀次确认,重新启动时间等待计时器。最后客户端和服务器都能
正常的关闭。假设客户端不等待2MSL,⽽是在发送完ACK之后直接释放关闭,⼀但这个ACK丢失的话,服务器就⽆法正常的进⼊关闭连
接状态。
两个理由:
1.保证客户端发送的最后⼀个ACK报⽂段能够到达服务端。
这个ACK报⽂段有可能丢失,使得处于LAST-ACK状态的B收不到对已发送的FIN+ACK报⽂段的确认,服务端超时重传FIN+ACK报
⽂段,⽽客户端能在2MSL时间内收到这个重传的FIN+ACK报⽂段,接着客户端重传⼀次确认,重新启动2MSL计时器,最后客户端
和服务端都进⼊到CLOSED状态,若客户端在TIME-WAIT状态不等待⼀段时间,⽽是发送完ACK报⽂段后⽴即释放连接,则⽆法收
到服务端重传的FIN+ACK报⽂段,所以不会再发送⼀次确认报⽂段,则服务端⽆法正常进⼊到CLOSED状态。
2.防⽌“已失效的连接请求报⽂段”出现在本连接中。
客户端在发送完最后⼀个ACK报⽂段后,再经过2MSL,就可以使本连接持续的时间内所产⽣的所有报⽂段都从⽹络中消失,使下⼀
个新的连接中不会出现这种旧的连接请求报⽂段。
2.4为什么TIME_WAIT状态需要经过2MSL才能返回到CLOSE状态?
理论上,四个报⽂都发送完毕,就可以直接进⼊CLOSE状态了,但是可能⽹络是不可靠的,有可能最后⼀个ACK丢失。所以TIME_WAIT状
态就是⽤来重发可能丢失的ACK报⽂。
3.总结
《TCP/IP详解卷1:协议》有⼀张TCP状态变迁图,很具有代表性,有助于⼤家理解三次握⼿和四次挥⼿的状态变化。如下图所⽰,粗的实
线箭头表⽰正常的客户端状态变迁,粗的虚线箭头表⽰正常的服务器状态变迁。
以后⾯试官再问你三次握⼿和四次挥⼿,直接把这⼀篇⽂章丢给他就可以了,他想问的都在这⾥。
参考:《TCP/IP详解卷1:协议》
ils/102366854","extend1":"pc","ab":"new"}">
原⽂链接:
[⾯试官,不要再问我三次握⼿和四次挥⼿](/hyg0811/article/details/102366854?ops_request_misc=%257B%2522request%255Fid%2
522%253A%2522678%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=1621868
3331678&biz_id=0&utm_medium=_arch_-task-blog-2~all~top_positive~_rank_v2_pc_rank
_v29&utm_term=%E4%B8%89%E6%AC%A1%E6%8F%A1%E6%89%8B%E5%92%8C%E5%9B%9B%E6%AC%A1%E6%8C%A5%E6%89%8B&spm=1018.
2226.3001.4187)
本文发布于:2022-12-04 06:20:09,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/88/49353.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |