zoukankan      html  css  js  c++  java
  • TCP传输控制协议

    TCP

    在TCP/IP协议模型中, 传输层协议有TCP和UDP, 这里主要介绍下可靠传输TCP协议, 目前是传输层协议首选.

    特点

    • 面向数据流(字节流形式)
    • 虚电路连接
    • 有缓冲传输(提供push机制 )
    • 无结构数据流(无边界)
    • 全双工

    连接建立

    socket接口使用 connect()时建立连接,  采用三次握手,  请看下图 :

    在这个过程中完成了几个重要功能 :

    1. 建立连接, 做好传送数据准备.
    2. 协商各自报文段初始序号ISN( 任意选取, TCP准规定不可为1, 其中一个原因是避免IP欺骗).
    3. 协商报文段最大长度MSS.

    为什么要三次握手 ?

    考虑正常情况:  主机A给主机B发送数据包, 在网络中丢失了. 主机A定时器到期后未收到来自主机B的确认, 于是A重新发送数据包, 主机B收到再发送确认.  如果之前的数据包没有丢失呢 ? 只是延迟了比较长的时间.  那么这个失效的数据包又重新发给主机B, 主机B以为A要建立连接, 会给A发送确认,  同意建立连接.   A肯定不会理它了,  所以主机B一直在那白白地等A传送数据, 所以采用三次握手能很好解决这个问题. 其他精彩回答可参考  https://www.zhihu.com/question/24853633

    可靠传输

    1.防止丢失

    如果限定一个时间之内未收到报文段的确认, 则认为该报文丢失, 进行重传.  超时定时器设定采用自适应动态算法.

    2.防止重复和乱序

    采用唯一序号机制. 这种方法相当于给每个字节编号, 体现了TCP面向数据流的特征

    3.确认机制

    1.确认指明期望收到下个报文段的序号, 而不是已经收到的报文段序号.

    2.累计确认(确认信息报告已经累积了多少个字节的数据).

    3.捎带确认(不单独发送确认信息, 捎带在自己发送的报文段中).

    拥塞控制

    慢启动算法:  发送方维持一个拥塞窗口cwnd的变量.  cwnd取决于网络拥塞情况动态变化, 也可以小于对方接收窗口.  开始不发送大量数据, 先发送试探报文, 一步步增大cwnd的值.

    为防止cwnd过大导致网络拥塞, 需要设置一个慢开始门限值ssthresh :

    当cwnd小于ssthresh时, 使用慢开始算法.

    当cwnd等于ssthresh时, 使用慢开始算法或拥塞避免算法都可以.

    当cwnd大于ssthresh时, 使用拥塞避免算法.

    拥塞避免算法 : 每进过一个RTT就把cwnd+1, 而不是加倍, 这样使得拥塞窗口线性增长.

    无论是在慢开始阶段还是在拥塞避免阶段, 只要发送方判断网络出现拥塞(未收到确认, 可能是丢失了, 也视为拥塞), 就把慢开始门限减小到拥塞窗口cwnd的一半, 并设置拥塞窗口大小为1, 执行慢开始算法.

    这里拥塞窗口的单位应该是字节数.

    快重传和快恢复

    要求接受方在收到一个失序的报文后立即发送重复确认, 而发送方在连续接收三个重复确认时要重传失序报文, 不必等待设置的超时计数器到期.

    在发送方收到三个重复确认以后, 执行乘法减小算法, 将门限值ssthresh减小到一半.

    在网络拥塞情况下, 有可能接收方收不到三个重复确认, 这是发送方认为网网络没有出现拥塞, 把cwnd设置为ssthresh大小, 然后执行拥塞避免算法.

    连接关闭

    断开连接使用四次挥手,  在客户端调用socket接口 close() 后发送FIN数据包,  参考下图:

    TCP连接是全双工的, 两个方向上都要关闭, 原则是发起关闭的一方发送FIN字段,  另一方接收到后必须发送关闭的确认. 从图中可以看出, 当收到FIN并不是立即关闭, 它是先发送确认, 然后再继续发送自己的FIN请求.

    需要注意的是 当客户端收到关闭确认ACK之后, 它仍然可以接受服务器的数据, 并且向服务器发送确认信息, 一个仅包含确认信息的报文不占用序号.

    客户端最后发送ACK后进入TIME_WAIT状态而不是CLOSED, 因为最后的这个ACK可能丢失,  如果是CLOSED话就已经断开连接了.  服务器方的这个连接关闭就会出错. 所以这里应该等待一段时间再进入CLOSED状态, 这个时间就是最大报文生存周期(MSL).

    异常关闭:   发送RST报文段,  立即停止传输,  关闭连接, 释放资源.

    半开放连接: 引入保活定时器, 指点时间之内仍然没有数据通信, 则发送侦查报文, 根据不同情况进行处理.

  • 相关阅读:
    day4
    cache用法
    Excel批量生成SQL语句,处理大量数据(增,改)
    IDEA中Maven依赖下载失败解决方案
    IDEA 自动生成类图 UML
    springboot报错说 Failed to parse multipart servlet request; nested exception is java.io.IOException
    controller层的引用service层一直报空指针问题
    CONCATENATE函数
    AQS
    String 类和常量池
  • 原文地址:https://www.cnblogs.com/tanxing/p/6784489.html
Copyright © 2011-2022 走看看