zoukankan      html  css  js  c++  java
  • TCP三次握手和四次挥手

     

    TCP的三次握手和四次挥手流程大家都很清楚,这里只对其中的某些细节进行学习。图1是三次握手与四次挥手的状态图

                       图1 TCP正常连接建立和终止所对应的状态

    问题一:为什么是三次握手,而不是四次握手或者是二次握手
    主要的解释有三点,逐一叙述:
    1.由图1可以看到第二次握手其实是服务器的SYN与ACK一起发送的,如果让服务器分别发送SYN和ACK,这样就是四次握手了,
    不过显然合并发送可以提高效率,所以就是三次握手,实质上是四次握手的优化
    2. 需要三次握手主要是为了保证信道可靠,如果信道可靠,无论什么时候发出消息,对方一定能收的到,三次通信是理论上的最小值,
    所以三次 握手不是TCP本身的要求,而是为了保证信道可靠
    3.为了避免网络中存在延迟的重复分组
    如果采用二次握手,只要服务器端发出ACK,新的连接就建立了。如果存在这样情况,如果之前在建立连接的时候,
    存在客户端的SYN报文由于网络延迟原因没有发送 到服务端,直到之前的连接释放的某个时间才到达服务端,此时服务器收到失效的SYN报文,
    就以为客户端再次发送的一个新的连接请求,如果是二次握手的话,这样 就建 立起连接,但是实质上客户端没有发送ACK,
    因此没有理睬服务器的确认,也不会向服务器发送数据。这样服务器还在苦苦等等客户端发送数据过来,这样服务器就 白白浪费很多资源。

    问题二:三次握手中如果有发包失败怎么办?
    1. 第一个包,即A发送B的SYN包中途被丢,没有到达B
    ---> A会周期性超时重传,直到收到B的确认
    2.第二个包,即B发给A的SYN和ACK中途被丢,没有到达A
    ----> B会周期性超时重传,直到收到A的确认
    3.第三个包,即A发给B的ACK中途被丢,没有到达B
    -->此时A发送完ACK,单方面认为TCP已经建立了,但是B没有认为连接建立了。
    ①:如果此时没有数据发送,B会周期性重传SYN和ACK,直到收到A的ACK为止
    ②:A发送完ACK,单方面认为连接已经建立,假定A有数据发送,B收到A的DATA+ACK。自然就可以建立连接了,也就可以接受DATA了
    ③:B如果有数据发送,数据发送不了,所以也会超时重传SYN和ACK

    问题三:四次挥手中客户端收到服务器的FIN后,处于TIME_WAIT状态,也叫2MSL状态 在这个状态等候2MSL时间有什么用处呢,为什么要等待2MSL时间?

    1:可靠的实现TCP全双工连接的终止
    存在这种情况,如果客户端收到服务器的FIN以后,发送FIN的ACK给服务器,但是服务器没有收到
    这个ACK,服务器会超时发送FIN,如果客户端不等待一段时间,将收不到重发的FIN,就不会重发
    ACK,这样就不能正确的关闭连接,那等待多久比较合适呢?首先服务器有一个超时时间,如果在这个
    超时时间内,收到了客户端的ACK,就可以正常关闭,如果收不到,就会重传FIN,所以这两段时间加起来就是
    服务器的timeout+FIN的传输时间,为了保守起见,采用更加保守的等待时间2MSL,如果2MSL时间内没有收到
    服务器的FIN,那就说明服务器端正确收到ACK了,如果收到了服务器的FIN呢,就客户端就重新发送ACK,这时候
    客户端又会等待2MSL时间。(MSL Maximum Segment Lifetime任何报文段被丢失前在网络内的最长时间)
    2: 允许老的重复字节在网络中消逝。

    关闭一个TCP连接后,过段时间后用相同的地址和IP建立另一个连接,新连接称为老连接的
    化身,因为他们的IP地址和端口号都相同,TCP必须防止来自前一个连接的老的重复分组在该连接终止后再出现。
    因为有可能目前的连接所用的端口和IP在连接断开后立即建立新的连接,新的连接和老的连接端口和IP都一样。如果
    网络中存在旧连接的重复字节,那么TCP协议就认为重复字节是属于新连接的,这样就可能和新的数据包发生混淆。
    为了因对这个问题,TCP不允许处于TIME_WAIT的状态的连接发起
    新的化身。即不允许再使用处于TIME_WAIT阶段的连接的IP 端口号进行连接,既然TIME_WAIT状态的持续时间为2MSL
    就可以保证让某个方向的分组最多存活MSL秒就被丢弃,另一个方向的应答报文最多存活MSL秒就被丢弃,
    通过实施这个规则,我们就能保证每成功建立每个TCP连接时,来自老连接老的重复分组都已经在网络中消逝了

    问题四:为什么关闭连接需要四次挥手?

    四次挥手是TCP的半关闭造成的,所谓的半关闭就是TCP提供了连接的一端在结束他的发送后还能接受另一端数据的能力
    TCP连接时全双工的,所以需要每个方向单独进行关闭,那么能将四次挥手中的第二步和第三步进行合并?这就变成了“三次挥手”了?
    原因是有可能服务端发送ACK的时候还需要发送数据给客户端,所以不能同时发送ACK和FIN,只能先将ACK发送到客户端
    等服务端发送完数据以后,再发送FIN到到客户端

     

  • 相关阅读:
    生活希望[置顶] 程序员的奋斗史(十六)——谈习惯
    评论数据库Win A Free Copy of Packt’s Managing Multimedia and Unstructured Data in the Oracle Database ebook
    下载方法[jBPM5 部署] 最可靠,最简洁方式
    美感地方Python禅
    关系方向机缘之始
    截止账户[置顶] 国际黄金强势上涨投资者加油~~~~~~
    数据库书籍大师推荐的Oracle数据库相关的书籍,收集汇总。
    输出空格杨辉三角 (a+b)的n次幂的展开式中各项的系数很有规律,对于n=2,3,4时分别是:1 2 1, 1 3 3 1,1 4 6 4 1。这些系数构成了著名的杨辉三角形:
    错误删除Its not about the outage
    noncompatible bean definition of same name and class
  • 原文地址:https://www.cnblogs.com/BGPYC/p/7635892.html
Copyright © 2011-2022 走看看