• TCP 如何处理失败重传呢?


    1  网络协议背景概念

    4层网络传输是基于udp基于端口

    7层网络协议传输是基于tcp基于端口(tcp的复杂度很高很高..),并在tcp之上添加了会话层表示层应用层

    upd协议面向报文,tcp协议 面上字节流。

    啥是面向字节流呢?

    2  TCP传输通信过程

    tcp面向字节流,udp面向报文。那tcp的字节流是怎样的呢?

    tcp是点到点的通信,建立tcp链接的两个端点,传输的数据不是报文,是一段数据中的一部分,并不知道一次读的数据是多少和发送次数。

    数据交给tcp层,由tcp决定一次发送多少数据,判断条件有很多,发送窗口、拥塞窗口、路径上的最大传输单元(MTU),输出队列数据总量等。

    如图在tcp发送数据之前,应用程序和tcp协议之间有一个tcp缓存队列,这个队列不固定字节大小,tcp要发送的数据也不固定字节大小,

    tcp是去发送数据的一部分字节流,

    并在这个传输中一直单向的进行。 ???????

    所以在网络传输中可以看到的是数据片段,然后是一组一组的数据交付给接收方。

    3  传输报错重传机制

    如果发送方发送 1 2 3 4 接收方只收到 1 2 回复确认 ack 3,然后发送方发来了 4,不能回复确认ack 5,因为不能跳跃确认。

    于是,采用重传机制,有2种:

    3.1  超时重传

    发送方不知道3 4 5 的接收情况,接收方一直在等 3,这中方式会有比较严重的问题。

    发送方有两种选择:

      a ,  默认 3 发送失败,重新发送3 

      b ,默认 3 4 5 发送失败,重传 3 4 5 

    a的方式,只传 3可能会慢,b的方式传 3 4 5 很快但是占用带宽,timeout也可能很长,这两个都不是最后的方法。

    3.2  快速重传

    tcp还有一种 快速重传 的算法,Fast-Retransmit,是以数据驱动重传,不是timeout时间驱动。

    怎么是以数据驱动呢?

    就是 如果只收到 1 2 ,回复ack 3 ,随后收到了 4 5 但是还没收到 3, 4 5的ack也回复 3 3,这样发送方会收到3个一样的ack,会知道传输出了问题

    这就是大部分tcp数据驱动重传机制(什么?大部分tcp,总共是有几个版本的..)。

    这种方式还不是最好的,只是解决了timeout的问题,回传的个数还是没解决,比如一次发了20条,就不知道是哪3个发的ack了,需要回传这20条。。

    3.3  sack 重传

    选择性重传,Selective Acknowledgement(sack),tcp的头会多一个SACK,快速重传的ACK还在。

    sack只回复已经到达的碎片,这样发送端就能准确知道是重传那部分字节流。在Linux可以用tcp_sack这个字段开启这个功能,2.4版之后的Linux默认开启。

    参考:https://tools.ietf.org/html/rfc2018  https://www.jianshu.com/p/69695f332a71

    遗留问题

    tcp重传还有一些问题,sack也不能完全相信:

    如果有接收端会将数据保存直到失败的分组重传,就会有接受方内存拥挤把收到的数据丢弃了,可能有。

  • 相关阅读:
    solr
    2.配置Flutter代码编辑器(IDE)
    1.Flutter的下载安装和环境配置
    ReactNative开发环境配置,新手踩坑必备.我也是新手
    汉字转拼音,获取汉字首字母
    For循环性能优化
    JavaScript滑块简易取色器
    C# 获取汉字拼音首字母(修正X问题,真正修正)
    团队项目-个人博客5.31
    团队项目-个人博客5.30
  • 原文地址:https://www.cnblogs.com/the-last/p/11524964.html
Copyright © 2020-2023  润新知