大家好,又见面了,我是你们的朋友全栈君。
Time_wait
啊,老哥们肯定会想,time_wait什么鬼? 为毛我主动断开tcp连接。发完最后一个ACK后不能直接断开连接啊,我能做的都做了。但是…..
老铁们你们想一下,ACK丢包是不会重传的,但是FIN呢? 最后被动关闭的一直要是收不到ACK它会怎么想,它肯定认为FIN包丢包了,那怎么样,重发呗。
重发之后呢,如果对端一直不会回复ACK,那么重传一定次数后就会发送重置报文段然后断开连接。那么这些精彩的来了,现在网络上有这么多FIN的重传包,如果主动断开连接的一方又重新立刻再次建立连接呢?直接血崩……
正传数据就会发现一个FIN段,怎么办呢?一看序列号不是当前连接里的序列号啊… 这怎么办只能发送重置报文段了关闭连接。这岂不是又浪费资源,又得不偿失影响下一次通信吗~~~~
所以主动断开的最后一个ACK发送完后,不能直接断开连接,它必须确保对方收到最后一个ACK才能断开连接,所以ACK过去一个MSL,如果ACK快到丢包这消耗了一个MSL,那么对端会重传FIN,这个FIN段又消耗了一个MSL,所以啊共2个MSL。所以time_wait时间俩个MSL。
所以说time_wait 就是为了防止在连接上有多个重传的FIN包出现,所以必须time_wait这个是为了防止当再一次建立相同的新连接时防止收到老连接的数据包从而导致的影响。
不知道这波解释为什么time_wait,老哥们听懂了没有
对于为什么3次握手?为毛不是2次/4次?
首先有个点是必须得知道的,tcp三次握手不止是为了建立连接,还要互相确认对方的当前的初始化序列号(这个序列号在Linux下是有哈希算法得来的),确保当前连接的安全性,如果不初始化,都是0开始的话,那么连接将不安全。其次还要互相决定下来MSL的大小。
所以如果2次握手。client 发生了 SYN + 自己的初始化序列号,server收到了,这时候server将 syn+ack+自己序列号回复给client , 如果这个包丢了,那么client将不知道server的序列号。但是server自己并不知道 这个syn+ack丢包了如果2次的话,那么client发现一直收到回复就重传了SYN段,那么server收到后,会知道自己的包丢了,就会再次重发syn+ack。假设这个包 client接到了,现在通信状态是OK的。不过这个假设是建立在server发完后没有立即发送数据段的前提下。
但是如果 server发完数据段,它认为是连通的,并立即发送一个数据,第一个syn+ack丢包了,client并不知道server的初始化序列号,突然收到了一个数据段,会发什么? 很简单,它误以为是上一个同一连接的延迟包,发送RST段,然后中断连接,直接雪崩!!!!
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/139583.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...