【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为Server端收到Client端的SYN请求报文后,可以直接发送SYN+ACK报文, 其中ACK报文是用来应答的。 SYN报文是用来同步的, 但是关闭连接时, 当Server端收到FIN报文时, 很可能不会立即关闭Socket,所以只能恢复一个ACK报文告诉Client, 你法的FIN报文我都收到了。 只有等到我Server端的所有报文都发送完了, 我才能发送FIN报文, 因此不能一起发送。 所以要用四次握手。
【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
四个报文都发送完毕,可以直接进入CLOSE状态,但是我们必须假设网络是不可靠的, 有可能最后一个ACK丢失。 所以TIME_WAIT状态就是用来重发可能丢失ACK报文。 在CLient发送最后的ACK回复,但该ACK可能丢失。 Server如果没有收到ACK, 将不断重发FINFIN片段。 所以Client不能立即关闭, 它必须确认Server收到了该ACK。 Client会在发送出的ACK进入到TIME_WAIT状态CLient会设置一个计时器, 所以等待2mSL时间。 如果在该时间内再次收到FIN, 那么Client会重发ACK并在此等待2msl。 所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
【问题3】为什么不能用两次握手进行连接?
3此握手完成两个重要的功能,既要双方做好发送数据的准备工作(双方都知道彼彼此已经准备好),也要允许双方就初始序列号进行协商,这个序列号在握手过程中被发送和确认。
两次握手时, 死锁可能发生。 作为例子, 考虑计算机通信, 假设C给S发送一个连接请求分组, 并发送了确定应答分组,按照两次握手的协定S认为连接已经成功地建立了, 可以开始发送连接数据分组, 可是, c在S的应答分组在传输中被丢失的情况下, 将不知道S是否已经准备好, 不知道S建立什么样的序列号,甚至C甚至怀疑S是否收到自己的连接请求分组, 在这种情况下。 C认为连接还未建立成功, 将忽略S发来的任何数据, 值能带连接确认应答分组。 而S在发出的分组超时候, 重复发送同样的分组。 这样就形成了死循环。
TCP超时重传
在发送某一个数据以后就开始一个计时器, 在一定时间内没有得到发送的数据包的ACK报文, 那么就重新发送数据, 直到发送成功位止。 影响超时重传机制协议效率的一个关键参数是重传超时时间。 RTO的值被设置为过大过小都会协议造成不理的影响。
- RTO设置长了, 重发就慢, 没有效率, 性能差。
- RTO设断了, 重发的就快, 会增加网络用塞, 导致更多的超时, 更多的超时导致更多的重发。
TCP滑动窗口
TCP滑动窗口的可靠性也是建立在确认重传的基础上的。
发送窗口只有收到对端对于本段发送窗口内字节的ACK确认,才会移动发送窗口的左边界。 接受端可以根据自己的状况通告窗口大小,从而控制发送端的接受,进行流量控制。