zoukankan      html  css  js  c++  java
  • 0.关于TCP协议的一些总结

      接触unix网络编程一年多了,偶尔用户态进程表现出一些不能理解的现象,因此将《TCP/IP协议卷1》TCP协议相关的章节通读了一遍,总结了一下相关的知识点。

    1.TCP数据报格式

      TCP封装在IP数据报中,如下:

    -------------------------------------------------------------------------------------

      |----IP首部(20字节)----||----TCP首部(20字节)||----TCP选项----||----TCP数据----|

      TCP数据包首部的格式如下:

      |--------16位源端口号---------------||--------------16位目的端口号--------------|

      |--------------------------------32位序号---------------------------------------|

      |--------------------------------32位确认序号-----------------------------------|

      |-4位首部长度-||-保留6位-||-TCPflag-||------------16位窗口大小------------------|

      |-----------16位校验和--------------||----------------16位紧急指针--------------|

      |-----------------------------------TCP选项-------------------------------------|

      |-----------------------------------TCP数据-------------------------------------|

    --------------------------------------------------------------------------------------

                        图1.TCP报头结构              

    2.TCP建立连接和断开连接

      tcp连接的建立需要经过三次握手:

    1.客户--SYN j-->服务器,客户状态:主动打开SYN_SENT,服务器状态:SYN_RCVD。

    2.服务器--SYN k,ack j+1-->客户,客户状态:ESTABLISHED,服务器状态:SYN_RCVD。

    3.客户--ack k+1-->服务器, 客户状态:ESTABLISHED,服务器状态:ESTABLISHED。

      tcp连接终止需要经过四次握手:

    1.客户--FIN m-->服务器,客户状态:FIN_WAIT_1,服务器状态:CLOSE_WAIT。

    2.服务器--ack m+1-->客户,客户状态:FIN_WAIT_2,服务器状态:CLOSE_WAIT。

    3.服务器--FIN n-->客户, 客户状态:TIME_WAIT,服务器状态:LAST_ACK。

    4.客户--ack n+1-->服务器,客户状态:TIME_WAIT或closed,服务器状态:closed。

      主动关闭的TCP一端会经历TIME_WAIT状态,从TIME_WAIT状态到closed状态经历2倍MSL的时间。MSL:报文最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。

      另外TCP头部的 flags包括{S-SYN、F-FIN、R-RST、P-PSH、.-其他},SYN是同步序号,FIN是发送方完成数据发送,RST复位连接,PSH尽可能快的将数据送往接收进程,. 以上四个标志比特均为0。

    3.呼入连接请求队列

      等待连接请求的一端有一个固定长度的连接队列,该队列中的连接已经被TCP接受,但还没有被应用层接受。

    区分:TCP接受一个连接是将其放入连接请求队列,而应用层接受连接是将其从该队列中移除。

    4.交互数据流和nagle算法

       交互数据总是以小于报文长度的分组发送。广域网环境,大量小分组的传输会导致网络拥塞,受延时的确认nagle算法用来减少广域网络传输的小分组的数目。

      受延时的确认:TCP接收端接收到数据时并不立即发送ACK;相反,它推迟发送,以便将ACK与需要沿该方向发送的数据一起发送。大多数实现采用时延为200ms。受时延的确认在接收端减少网络传输小分组的数目。

      nagle算法:TCP连接上的发送方最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其他的小分组,TCP发送方收集这些少量的分组,并在确认到来时以一个分组的方式发送出去。nagle算法在发送端减少网络上小分组传输的数量。

    对于交互用户而言,nagle算法会产生明显的时延。

    5.滑动窗口协议

       滑动窗口协议是TCP流量控制的一种方式,与之相对的是停止等待协议(TFTP使用)。滑动窗口协议允许发送端在停止等待确认前,可以发送多个分组,与停止等待协议相比,滑动窗口协议加速了数据的传输,接收方看到的滑动窗口结构如图2所示。

    ------------------------------------------------------------------------------------

                             |----接收方通告,提供的窗口-----|

                          |-可用的窗口-|

    |-----1------2-----3-----4------5-----6-----7------8-----9-----10------11----.....

        |-发送被确认-|     |-发送未确认-|     |-能够发送的-|     |-不能发送 

    ------------------------------------------------------------------------------------

                         图2.滑动窗口接口   

       发送方根据接收方通告的窗口大小,计算可用的窗口大小,该窗口表明多少数据可以立即被发送出去。随着分组的发送以及被确认,窗口的两个边沿会不断右移:

      1.窗口左边右移,窗口合拢,导致原因:数据被发送并且被确认时。

      2.窗口右边右移,窗口张开,导致原因:接收方接收进程读取了接收缓冲区的数据,释放了接收缓存,并且发送了新的窗口通告给发送方。

      从上面可以看出,导致滑动窗口张开是接收方产生新的窗口通告,因此滑动窗口是接收方流量控制的措施。

    6.紧急方式

       通过设置TCP首部的两个字段来发出紧急通知:从一端到另一端的紧急数据已经被放置在数据流中。URG比特被置1,并且16比特的紧急指针被置为一个正的偏移量。可以利用tcp的紧急方式实现tcp通信双方的心搏。

    7.带宽时延积

      带宽时延积用来描述一个tcp管道的容量:

        capcity(bit) = bandwidth(b/s) * round-trip time(s)

    只有当管道被填满时,才能达到最大的吞吐量。对于高延迟和大带宽的肥胖管道,增加tcp发送和接收缓冲区,才能填满tcp管道,达到最大的吞吐量。

    7.慢启动和拥塞避免算法

      慢启动:为发送方tcp增加了另外一个窗口-拥塞窗口,cwnd。当tcp连接建立时,拥塞窗口大小被初始化为一个报文段长度,每收到一个ack,cwnd就增加一个报文段的长度,发送方取拥塞窗口与通告窗口的最小值作为发送上线。拥塞窗口cwnd是发送方的流量控制方式,另外cwnd在开始阶段指数方式增长,慢启动是在一个连接上发起数据流的方法

      拥塞避免算法是一种处理分组丢失的方法,与慢启动是不同,当处于拥塞避免阶段时每收到一个ack,cwnd增加cwnd/1,拥塞避免阶段cwnd呈线性方式增长。

      慢启动算法和拥塞避免算法通常一起工作,这两个算法需要对每一个连接维护两个变量:cwnd和慢启动门限ssthresh。大致的工作过程:

      1.对于一个给定的连接,初始cwnd为1个报文段,ssthresh为65535个字节。首先是当前窗口没有达到65535时,采用慢启动的方式进行分组的传输。

      2.当拥塞发生时(超时或者收到重复的确认),ssthresh被设置成当前窗口大小的一半。此外,如果是阻塞引起的超时,则cwnd被设置成1个报文段。

      3.当有新的ack到达时,就增加cwnd,增加的方法依赖于是否是慢启动或者拥塞避免。如果cwnd小于或等于ssthresh,则执行慢启动,否则拥塞避免。慢启动时,指数方式增加cwnd,拥塞避免时,线性方式增加cwnd。

      关于分组的传输,还存在快速重传快速恢复的算法。所谓的快速重传,即当连续收到3个重复的ack时,就确认对应分组丢失,不等待超时定时器溢出,而直接重传对应分组。当确认分组丢失,执行快速重传后,不是去执行慢启动将cwnd的值置为1,而是执行拥塞避免算法,这就是快速恢复算法。

    8.TCP坚持定时器和糊涂窗口综合症

      当发送方tcp接收到窗口大小为0的窗口通告时,发送方将停止发送数据,并且设定一个坚持定时器来周期性的像接受发查询,以便发现窗口是否已经增大,这些从发送方发出的报文段成为窗口探查。坚持定时器使用tcp 500ms定时器,并采用了tcp指数退避,但是坚持定时器总是在5~60S之间。窗口探查会一直持续,直到窗口被打开,或者tcp连接被关闭

      糊涂窗口综合征:少量的数据将通过连接进行交换,而不是满长度的报文段。糊涂窗口综合征,降低了tcp的有效吞吐量。避免糊涂窗口综合征,可以在发送方或者接收方的任何一方采取措施:1.接收方不通告小窗口,2.发送方才一般情形下避免发送小的报文段。 

    9.keepalive定时器

       如果一个给定的tcp连接在两个小时之内没有任何动作,则服务器就向客户发送一个探查报文段。客户可能处于一下状态:

      1.客户主机依然正常运行,并从服务器可达:客户的tcp响应正常。

      2.客户主机已经崩溃,并且关闭或者正在重新启动:服务器探查报文段收不到响应,75s后超时,一直持续发送共10个探查,间隔75s,如果仍然没有收到响应,则认为客户主机已经关闭。

      3.客户主机崩溃并已经重新启动:服务器将收到一个复位,使得服务器终止这个连接。

      4.客户机正常运行,但从服务器不可达:和1中情形类似。

  • 相关阅读:
    Linux下的ping命令
    git stash
    ansiable
    「疫期集训day4」硝烟
    「线段树」「单点修改」洛谷P1198 [JSOI2008]最大数
    「状压DP」「暴力搜索」排列perm
    「疫期集训day3」要塞
    「疫期集训day2」高地
    「疫期集训day1」无言
    「区间DP」「洛谷P1043」数字游戏
  • 原文地址:https://www.cnblogs.com/VincentXu/p/3194342.html
Copyright © 2011-2022 走看看