趣谈网络协议笔记-二(第十二讲)

TCP协议(下):西行必定多妖孽,恒心智慧消磨难


前言

哈哈哈,越当我看刘超的通俗讲解,我就越感觉自己的无能。每次当我看了讲解之后,每次当我感觉到这个东西原来是这么简单的东西时,都会情不由衷地感觉到自己,到底是有多么的软弱,多么的脆弱。因为既然是别人打算讲解给你听的东西,那么别人一定是做好充分准备,力求让自己所讲的东西就算是让一头猪来听,都能听得似是而非的。

那么既然是连猪都能听得懂的事情,我能听得懂到底有什么值得沾沾自喜的呢?所以,当参加任何的培训的时候,听别人侃侃而谈,当你感觉他所说的事情似乎很简单的时候,请注意,此时你应该反问自己,“如果他不讲,我知道这些吗?”如果并不是,那么并不是他讲的东西对于你来说太过于简单,仅仅是他比较擅长将复杂的,晦涩的事情讲的简单而已。

我也感觉到,如果今天我不为自己的脆弱而努力,那么明天,我绝对会为自己的脆弱而买单!

今天在公司同一层楼遇到了我的高一同学,为什么不是高中同学呢,因为高一分实验班的时候我入选了= =!大概算了算,8年了呢,茫茫13亿人,能再次相遇也算是一种缘分,找个时间,吃顿饭好好聊聊吧,这几年真的是发生了很多事情呢。

共勉!王国兴废,在此一战,诸君努力!

正文

上一讲主要讲的是TCP协议在客户端和服务器端之间是如何建立和停止可靠(相对UDP)的连接的。
这一讲则是用以讲述,在建立起可靠的连接之后,客户端和服务器是如何执行可靠的数据传输的。

这一讲不像上一讲一样,我能想到比较好的载体,所以晚上犹豫了一下,到底应该怎么进行描述和表达才能将自己所理解的事情很清晰地展现给读者,最近,也在进行学习,如何记录可视化笔记,我相信,等我学成,博客表达什么的将不再是问题。

那么客户端是如何通过TCP协议将数据可靠地发送到服务器的呢?我们不妨做一个比喻,将客户端比作老师,将服务器比作学生,将数据传输比喻成老师给学生布置作业

作为老师一方,升学率的压力其实逼迫着老师只能尽可能地让学生花费更多的时间来学习,其中最简单的方式当然是布置作业。但是,布置的作业数量也绝对不能太过分,毕竟学生的时间的精力有限,如果作业超出了学生的负担,一般就会导致两个结果,学生连作业都背不动“丢包”,学生到交作业的时候作业没有做完“服务器不处理包”。

所以这里就师生之间就需要进行一些协商了,在布置作业的时候,学生就会说,“老师,行行好吧,我今晚肾虚,最多只能做这么多的作业了”(在包头中声明窗口大小)。老师也很好说话,“那好吧,今天晚上我就布置这么多的作业,但是这些作业你一定要完成啊”(客户端就基于服务器传回来的窗口大小来控住发送包的频率,注意,是基于,而不是完全按照)。请注意,学生完成作业,老师是要检查的,但是一般很少会有老师会让学生每完成一页作业,就给老师打一个电话(即每收到一个id的包就返回一次应答),那全班那么多的学生,老师也忙不过来。所以老师一般一天检查一次作业,学生将前一天的作业的完成情况进行一次汇总,汇报给老师(服务器会应答某个之前的id,表示都收到了,称为“累计确认”)。

之前也说过了,老师在布置作业的时候,也需要考虑学生在路上抗不抗的动,比如说,”我给你一堆坦克零件,你回去给我组装好!“学生的负载能力也是需要考虑在内的(坐车啊,坐飞机啊)。

教师布置的作业多少毫无疑问要基于以上两点,负载能力(网络的传输效能cwnd)和学生执行力(服务器的处理效能rwnd),往往取其中的弱者,短板效应。公式如下
LastByteSent - LastByteAcked <= min{cwnd,rwnd}

首先我们先默认学生的能力是那块短板,即窗口的大小受服务器的缓存大小所影响。

客户端维护一张需要通过TCP协议进行传输的包的序号表,表中分为四个部分
* 发送已确认:老师已经布置,学生已经完成的作业页数
* 发送未确认:老师已经布置,但是学生还在做,不知道有没有完成
* 未发送可发送:老师感觉学生今天作业太少,打算在家长群里额外布置的作业
* 未发送不可发送:老师预期明天要布置的作业

与之相对的,服务器端也维护一张序号表,用以表示具体接收到包的序号数据信息,表的结构相对比较简单,分为三个部分:
* 接收已确认:老师已经布置,学生已经完成的作业
* 等待接收未确认:老师已经布置,我正在做的作业
* 不能接收:老师超过我的能力,布置的作业,我当天也没有办法完成

之前所说的”累计确认“就是指当发现1-5的序号包都已经收到了,就会应答序号5的包,表示1-5序号的包我都已经接收成功了。

那么如果我有一个包丢了怎么办呢?我们一般会设置一个超时时间RTT,如果超过了超时时间,但是还没有接收到ack应答包,就重新发送一次,同时将超时时间设置为原来的两倍。如果遭遇到了两次超时,那就说明,网络情况很糟糕,不适合反复发送。

当然不仅仅是客户端对丢包会做出反应,服务器端如果遇到了类似5号包都到了,但是4号包还没有到,就会连续发送三次基于3的ack包,来表示需要重新传输4号包。

另外,也可以通过在TCP头传输一个名为SACK(selective acknowledge)的东西,来表示服务器端缺乏了特定的包,ACK3,SACK5,SACK6。

OK,还有拥塞控制的TCP解决方案没有处理。
客户端对于网络情况其实是缺乏客观性了解的,对于客户端来说,与服务器端之间的网络就像是一个黑盒。作为客户端只能通过试探来逐渐摸清楚中间网络的情况。
思路如下:先假定网络的传输能力的极限为sshresh=65535,cwnd=1
传输一次,发现没有丢包,那么将当前cwnd翻倍试试看,即cwnd=2
以此类推,最后会归到两种情况
1. cwnd超过sshresh,这个传输速度已经足够满足大多数需求了,当然如果有资源绝对不能浪费,所以如果传输过程中还没有丢包,那么cwnd+1
2. cwnd达到一定的值时发生了丢包的情况,这个时候,我们认为我们过于乐观地估计了网络的情况,所以就将sshresh设置为当前cwnd的一半,如果是客户端发现丢包了,那么cwnd从1开始重新努力;但是如果是服务器端发现丢包了,这个情况好一些,那么cwnd就会很乐观地按照情况1的逻辑继续探测中间的网络情况。

当然,这样的探测有两个问题:
1. 丢包并不代表着通道满了,也可能是管子本来就漏水。例如公网上宽带不满也会丢包,这个时候就认为拥塞了,退缩了,其实是不对的。
2. TCP的拥塞控制要等到中间设备都填充满了,才发生丢包,从而降低速度,在这个时候已经晚了。其实TCP只需要填满管道就可以了,不应该接着填,直到连缓存也填满。

为了优化这两个问题,后来有了TCP BBR拥塞算法。它企图找到一个平衡点,就是通过不断地加快发送速度,将管道填满,但是不要填满中间设备的缓存,因为这样时延会增加,在这个平衡点可以很好的达到高带宽和低时延的平衡。

趣谈网络协议笔记-二(第十二讲)相关推荐

  1. 趣谈网络协议笔记-二(第十九讲)

    趣谈网络协议笔记-二(第十九讲) HttpDNS:网络世界的地址簿也会指错路 自勉 勿谓言之不预也 -- 向为祖国牺牲的先烈致敬! 引用 dns缓存刷新时间是多久?dns本地缓存时间介绍 - 东大网管 ...

  2. 趣谈网络协议笔记-二(第十八讲)

    趣谈网络协议笔记-二(第十八讲) DNS协议:网络世界的地址簿 自勉 勿谓言之不预也 -- 向为祖国牺牲的先烈致敬! 正文 DNS用于域名解析,但也不仅仅是用于域名解析,不仅仅是将域名转换成IP. 在 ...

  3. 趣谈网络协议笔记-二(第十六讲上)

    趣谈网络协议笔记-二(第十六讲上) 流媒体协议:如何在直播里看到美女帅哥? 自勉 给岁月以文明,而不是给文明以岁月!--<三体> 在触不到的獠牙上点火--就像不必仰望那星星就能够解决--就 ...

  4. 趣谈网络协议笔记-二(第十三讲)

    趣谈网络协议笔记-二(第十三讲) 套接字Socket:Talk is cheap, show me the code 前言 这只是笔记,是为了整理刘超大神的极客时间专栏的只是而存在的! 经常会在网络上 ...

  5. 趣谈网络协议笔记-二(第十讲)

    趣谈网络协议笔记-二(第十讲) UDP协议:因性善而简单,难免碰到"城会玩" 自勉 如果手上没有剑,我就无法保护你.如果我一直握着剑,我就无法抱紧你.--<Bleach> ...

  6. 趣谈网络协议笔记-二(第十五讲)我与刘超有不同看法

    趣谈网络协议笔记-二(第十五讲) HTTPS协议:点外卖的过程原来这么复杂 前言 好饿啊= =,最近感觉自己真的是胖的不行了,所以开始了适当的节食操作. 我似乎很不擅长隐藏自己的想法.我似乎很不习惯于 ...

  7. 趣谈网络协议笔记-二(第五讲)

    趣谈网络协议笔记-二(第五讲) 目录 第二模块 底层网络知识讲解:第二层到第三层 第5讲 | 从物理层到MAC层:如何在宿舍离自己组网完联机游戏 第6讲 | 交换机与VLAN:办公室太复杂,我要回学校 ...

  8. 趣谈网络协议笔记-二(第十七讲)

    趣谈网络协议笔记-二(第十七讲) P2P协议:我下小电影,99%急死你 自勉 逃离舒适区! 正文 一. P2P协议 整个篇章讲的就是这两个协议之间的区别.P2P协议就是迅雷下载数据时所用的协议, 众所 ...

  9. 趣谈网络协议笔记-二(第十一讲)

    趣谈网络协议笔记-二(第十一讲) TCP协议(上):因性恶而复杂,先恶后善反轻松 自勉 我似乎天性不擅长争斗,但是有些时候,我也必须砥砺前行. 强大是和平的前提,而善良不是. 前言 今天回到家里已经是 ...

最新文章

  1. 机器学习初学者都应该知道的5类回归损失函数
  2. 基于 ELK Stack 和 Spark Streaming 的日志处理平台设计与实现
  3. php集合与数组的区别,java集合与数组的区别
  4. Google的面试题长啥样
  5. 压缩、解压 解决 客户端查询大批量数据时等待时间过长的问题
  6. 关于IE6、7、8下实现盒阴影的几个注意点
  7. 华为项目Tree canvas画图2
  8. 一个汉字在数据库占几个字节
  9. php数组的奇数_PHP - 查找数组元素是奇数还是偶数
  10. 混日子不是你的错,根源在这里
  11. 【论文】哈工大SCIR Lab | EMNLP 2019 基于BERT的跨语言上下文相关词向量在零样本依存分析中的应用...
  12. Struts2常量配置
  13. html中加载页面时调用函数,js页面加载时调用函数方法
  14. 数学建模专栏 | 第十一篇:MATLAB CUMCM真题求解实例二:优化型
  15. tftp命令下载或上传文件
  16. MoveIt2——4.机器人模型和机器人状态
  17. ftp客户端工具,几款优秀的ftp客户端工具
  18. 开放平台-web实现QQ第三方登录
  19. AssertionError: Invalid device id
  20. 骁龙695和骁龙750g哪个好

热门文章

  1. 怎么用python找因子_在python中有大量因子
  2. python解析器_Python Python解析器
  3. Python3搭建Django框架浅析
  4. web系统 手机app 能访问吗?_成都APP开发:原生APP开发与Web APP开发有什么区别呢?...
  5. ssm路径访问不到_ssm整合!!!
  6. win7怎么清理java缓存文件夹_Win7怎么清除浏览器缓存?清除电脑缓存的妙招
  7. python datetime.datetime 当前_python之time和datetime的常用方法
  8. mysql的一个字段最多能插入多少数据?我们存入text类型的值上限是多大?
  9. java线程池的使用例子,不愧是大佬
  10. Open Neural Network Exchange(ONNX)概述