zoukankan      html  css  js  c++  java
  • TCP/IP第四层协议TCP(二)连接的建立与终止

    toc

    TCP是有连接的

    TCP是一个面向连接的协议。双方想发送数据之前,必须在双方之间有一条连接。

    建立连接的过程

    握手与序号

    发送第一个SYN的一端将执行主动打开(active open)。接收这个SYN并发回下一个SYN的一端执行被动打开(passive open)。
    当一端为建立连接而发送它的SYN时,它为连接选择一个初始序号(ISN)。ISN随时间而变化,因此每个连接都将具有不同的ISN。ISN是一个32比特的计数器,每4ms加1。这样选择序号的目的在于防止在网络中被延迟的分组在以后又被传送,而导致某个连接的一方对它作错误的解释。
    一个SYN将占用一个序号,接收到SYN的一端必须发送一个发送SYN一端ISN值+1的ACK进行确认。
    图中发送端与接收端就各发送了一个SYN,且两个SYN都拥有各自的序列号,但是回复的ACK总是收到的上一个的ISN值加1。

    为什么握手是三次,而不是两次与四次:

    • 为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
    • 如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认
      https://blog.csdn.net/lengxiao1993/article/details/82771768

    MSS

    图中还有MSS字段,MSS( Maximum Segment Size,最大报文段长度)表示TCP报文段每次能够传输的最大数据长度,不包含首部部分。
    MSS由双方在建立连接时协商(MSS选项只能出现在SYN报文段中),每一方都会通告对方自己期望的MSS大小,双方会在通告的MSS值中取最小值作为这次连接的MSS值,但如果不接收对方的MSS值,MSS就设为默认的536字节。
    在没有分片的情况下,MSS越大越好,MSS越大每个报文段传输的数据接越多,网络利用率也越高。要避免分片,因为除了分片与重组除了会带来额外的开销之外,当仅有一个分组丢失后整个TCP报文段都会被重传,这会影响TCP的性能和网络吞吐率。所以MSS通常的通过MTU值计算,即通常情况下MSS = MTU -20字节 IP首部大小 - 20字节 TCP首部大小

    连接建立过程中的状态变迁

    终止连接的过程


    建立一个连接需要三次握手,而终止一个连接要经过四次挥手。这由TCP的半关闭(halfclose)造成的。既然一个TCP连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。
    当一端收到FIN后,意味着它不会再收到另一端发送的数据(除了ACK),但是它仍然能够向另一端发送数据(半关闭)。
    首先进行关闭的一方(即发送第一个FIN的那方)将执行主动关闭,而另一方(收到这个FIN的一方)执行被动关闭。通常一方完成主动关闭而另一方完成被动关闭。

    连接终止过程中的状态变迁

    TIME_WAIT状态

    TIME_WAIT状态也称为2MSL等待状态。只有执行主动关闭的一端才会有此状态,被动关闭的一端不会有。
    每个具体TCP实现必须选择一个报文段最大生存时间MSL(Maximum Segment Lifetime)。它是任何报文段被丢弃前在网络内的最长时间。MSL的标准值是2分钟,根据不同的实现,可能是30秒、1分钟或2分钟。
    当执行主动关闭的一端收到被动关闭的一端发送的FIN并回复ACK后,必须在TIME_WAIT状态停留的时间为2倍的MSL时间。当回复的ACK丢失时,这可以让主动关闭端有机会再次用ACK回复被动关闭端的FIN( 被动关闭端收不到ACK超时而重发的FIN)。
    在2MSL等待时间内,对应的插口对是不能被再次使用的,直到超过2MSL时间。并且在2SML时间内,任何迟到的报文段都将会被丢弃。

    平静时间

    TCP在重启的MSL时间内不能建立任何连接

    FIN_WAIT_2状态

    执行主动关闭的一方发送了第一个FIN 并且接收到了ACK 之后,会进入FIN_WAIT_2状态。
    只有当另外一方发送第二个FIN来关闭另外一个方向的连接,并在主动关闭方接收到第二个FIN之后,才会从FIN_WAIT_2状态转换到 TIME_WAIT状态。
    半关闭时,执行主动关闭的一方会一直处于FIN_WAIT_2状态,另一方将会一直处于CLOSE_WAIT状态

    复位报文段

    首部中的RST是用于复位的,当收到一个RST后,不会回复ACK并且会立即断掉TCP连接。
    三种情况下会出现RST报文段:

    1. 目标端口没有开启服务时
      当向一个没有被listen的端口建立连接时,发起SYN的一方将会收到RST(如果是UDP,且对方没有开启UDP服务的,则会返回一个端口不可达)
    2. 异常关闭时
      四次挥手是终止一个连接的正常方法,这也被称为有序释放。发送RST报文段来终止一个连接,就被称为异常关闭。
      异常终止一个连接对应用程序的两个优点:
      • 可以丢弃任何待发送数据(缓冲区会被清掉)并立即发送RST报文段。
      • RST报文段的接收方可以区别另一方执行的是异常关闭还是正常关闭,应用程序可以通过API对异常关闭进行处理。
    3. 检查半打开连接
      当一方已经关闭或异常终止连接而另一方却不知道时,这样的TCP连接就是半打开连接。(如客户端断电)
      当发生半打开连接时,TCP一方在接收另一方的报文段却又不认识这条连接时,会回复一个RST报文段。




    原创不易,转载请注明出处,谢谢
  • 相关阅读:
    LeetCode 152. 乘积最大子数组
    LeetCode 148. 排序链表
    LeetCode 143. 重排链表
    LeetCode 142. 环形链表 II
    LeetCode 137. 只出现一次的数字 II
    LeetCode 127. 单词接龙
    LeetCode 120. 三角形最小路径和
    spring boot redis 数据库缓存用法
    堪称神器的Chrome插件
    rocketMQ安装中遇到的坑
  • 原文地址:https://www.cnblogs.com/Keeping-Fit/p/14116508.html
Copyright © 2011-2022 走看看