zoukankan      html  css  js  c++  java
  • TCP三次握手中SYN,ACK,seq ack的含义

    转至:https://www.cnblogs.com/muyi23333/articles/13841268.html

    1.TCP 为什么三次握手而不是两次握手

    1.防止已失效的连接请求又传送到服务器端,因而产生错误。

      不幸的是, 这种解释是不准确的, TCP 采用三次握手的原因其实非常简单, 远没有大部分博客所描述的那样云山雾绕。为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

    位码即tcp标志位,有6种标示:

    ①  SYN(synchronous建立联机);

    ②  ACK(acknowledgement 确认)

    ③  PSH(push传送)

    ④  FIN(finish结束)

    ⑤  RST(reset重置)

    ⑥  URG(urgent紧急)

    Sequence number(顺序号码) //Acknowledge number(确认号码)

    第一次握手:主机A发送位码为SYN=1,随机产生seq number=1234567的数据包到服务器,主机B由SYN=1知道,A要求建立联机;

    第二次握手,主机B收到请求后要确认联机信息,向A发送ack number=(主机A的seq+1),SYN=1,ACK=1,随机产生seq number=7654321的包;

    第三次握手:主机A收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ACK是否为1,若正确,主机A会再发送ack number=(主机B的seq+1),ACK=1,主机B收到后确认seq值与ACK=1则连接建立成功。

    sequence number:表示的是我方(发送方)这边,这个packet的数据部分的第一位应该在整个data stream中所在的位置。(注意这里使用的是“应该”。因为对于没有数据的传输,如ACK,虽然它有一个seq,但是这次传输在整个data stream中是不占位置的。所以下一个实际有数据的传输,会依旧从上一次发送ACK的数据包的seq开始)

     

    acknowledge number:表示的是期望的对方(接收方)的下一次sequence number是多少。

    注意SYN/FIN的传输,虽然没有data,但是会让下一次传输的packet seq增加一但是,ACK的传输,不会让下一次的传输packet seq加一

    题外话

    有一位读者关注到了三次握手中, 序列号变化的问题, 让笔者临时想起了曾经困扰自己的一个问题

    为什么三次握手最后一次握手中, 在上面的示意图中回复的 seq = x+1 。

    acknowledgement number 的作用是向对方表示,我期待收到的下一个序号。 如果你向对方回复了 ack = 31, 代表着你已经收到了序号截止到30的数据,期待的下一个数据起点是 31 。

    TCP 协议规定SYN报文虽然不携带数据, 但是也要消耗1个序列号, 所以前两次握手客户端和服务端都需要向对方回复 x+1 或 y+1 。

     

     值得注意的是, 如上图所说, 最后一次握手在默认不携带数据的情况下, 由于SYN 不是 1 , 是不消耗序列号的。 所以三次握手结束后, 客户端下一个发送的报文中 seq 依旧是 x+1, 示意图如下

    注意到, 上图第四步发送的 seq 和第三次握手的 seq 是一样的, 体现了最后一次握手, 默认不消耗序列号的特点。

    四次挥手

     

    四次握手是指终止TCP连接协议时,需要在客户端和服务器之间发送四个包

    第一次挥手:主动关闭方发送第一个包,其中FIN标志位为1,发送顺序号seq为X。

    第二次挥手:被动关闭方收到FIN包后发送第二个包,其中发送顺序号seq为Z,接收顺序号ack为X+1。

    第三次挥手:被动关闭方再发送第三个包,其中FIN标志位为1,发送顺序号seq为Y,接收顺序号ack为X。

    第四次挥手:主动关闭方发送第四个包,其中发送顺序号为X,接收顺序号为Y。至此,完成四次挥手。

    超时重传指的是,发送数据包在一定的时间周期内没有收到相应的ACK,等待一定的时间,超时之后就认为这个数据包丢失,就会重新发送。这个等待时间被称为RTO. 

    深入讨论:

    1、为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

        建立连接时,ACK和SYN可以放在一个报文里来发送。而关闭连接时,被动关闭方可能还需要发送一些数据后,再发送FIN报文表示同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。 

    2、为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?

        两个存在的理由:1、无法保证最后发送的ACK报文会一定被对方收到,所以需要重发可能丢失的ACK报文。2、关闭链接一段时间后可能会在相同的IP地址和端口建立新的连接,为了防止旧连接的重复分组在新连接已经终止后再现。2MSL足以让分组最多存活msl秒被丢弃。 

    3、为什么必须是三次握手,不能用两次握手进行连接?

        记住服务器的资源宝贵不能浪费!  如果在断开连接后,第一次握手请求连接的包才到会使服务器打开连接,占用资源而且容易被恶意攻击!防止攻击的方法,缩短服务器等待时间。两次握手容易死锁。如果服务器的应答分组在传输中丢失,将不知道S建立什么样的序列号,C认为连接还未建立成功,将忽略S发来的任何数据分组,只等待连接确认应答分组。而S在发出的分组超时后,重复发送同样的分组。这样就形成了死锁。

    参考:https://blog.csdn.net/qq_25948717/article/details/80382766

     

  • 相关阅读:
    Windows Mobile下创建cmwap接入点
    我的云之旅hadoop单机设置(2)
    ssh登录
    我的云之旅前言(1)
    实时搜索将是下一个核心
    cassandra索引目录
    图书大甩卖(操作系统、C语言、Linux) 已成交
    ehcache实例
    google推出语音搜索
    百姓网看起来还行
  • 原文地址:https://www.cnblogs.com/my-first-blog-lgz/p/14788810.html
Copyright © 2011-2022 走看看