写这篇文章前,我有些肺腑之言想感谢一下我的微信好友“风大”。 是他给了我信心,原来没有很难的技术,只要你肯努力总能赶上其他人。 后来关注他的博客后,发现他尽然觉得弄懂hashmap的 最好办法是自己实现一个hashmap。一开始我也是不懂为什么要这样,后来发现读懂hashmap之后,再自己实现的时候,刚好可以读懂hashmap中那些设计巧妙的地方,发现自己与大师的差距。最后我也总结了一个学习方法: 先弄懂一个技术怎么样,再考虑如果是自己去设计会是什么样子,一开始就算是抄,抄多了你就会自己写了。 之前写过一个springMVC的小轮子,后来看spring事务机制的时候 ,又写了一个TransactionManage。 这些东西就像高冷的美女,只有你征服她时,你才能感受到她平凡而又不普通的一面。
开始进入话题: 两个物理节点之间的网络传输 如果不建立在7层网络模型或者是5层网络模型的基础上,一定是不安全的。 那为了让网络传输变得安全,所以5层网络模型就每层都加了点东西,来给我们的网络传输带来一些保障。 没有数据链路层,你怎么把数据打包发出去呢? 没有网络层,你怎么把你的爱说给你的女神呢? 没有传输层,你怎么保证你的女神就能收到你的爱呢? 没有应用层,你女神怎么知道你按什么协议来发,他按什么协议来接呢?HTTP 还是 FTP?
好的,今天我们重点来谈谈,传输层怎么让女神收到你的爱。一分不多,一分不少。
在网络传输的过程中,经常会出现丢包,重复包,发错了,发的顺序不对等各种各样的问题。 在传输层中使用的协议是 TCP/IP协议。 TCP协议 维持着 发送方 and 接收方 的缓冲区、 双方商定包的重传机制。接收方如何来ack 发送方发过来的包。
首先我们看看 如果生活中的两个人发消息是怎么发的,然后映射到网络上:
发送方发一个包1,接收方就确认一个包1,这样看起来,逻辑上并没有问题。 不会出现丢包呀,发重复包,发错包了,发的顺序不对的情况。 但是,问题来了,一个数据包的大小并不大,你一来我一回的,就导致了这个方案,发送消息的吞吐量上不去。如果你了解一些操作系统,多线程方便的知识,或者看过我之前关于cpu处理能力及redis 为什么是单线程的文章, 你一定知道,对于硬盘,还有网络这种“慢速通道”,频繁的多次IO绝不是一个好的方案,是可以将多次请求放到一个buff中,然后统一由这个buff 把多个消息拼在一起发送过去的。
所以改进的方案就来了,我可以将多个消息放在一起再发送过去,然后对方也可以一次性接受多个消息,只要顺序是对的就可以了嘛,我们接着来看怎么做。
滑动窗口协议就随之产生了:
滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致接收方接受不赢,导入数据丢失的问题。
关于滑动窗口协议可以使用搜索引擎或者上知乎了解:TCP协议的滑动窗口协议
看看滑动窗口协议是什么样子的:
如果传输的过程中丢包了怎么办呢?
发送方丢包了,接收方不会回复ack标识,同时又因为接受方的滑动窗口大小是已经确定了的。所以并不会发送后面栏位的包。 那自然丢包了就要重发~ 重发的时候是什么样呢?
发送方发5号包,丢包时,滑动窗口协议会继续的把6 7 号包发过去,但是接收方并没有收到5号包,滑动窗口协议,为了保证 传输的顺序,接收方不会把 6 7号包的ack给发送回来, 只有在5号包重发后,并且接收方接收到了五号包的时候,接收方才会将 5 6 7 号包的ack 再重新返回。 5 6 7号包的 ack 返回后, 滑动窗口又可以向右移动三位 去传 12 13 14号包了。
这样丢包的问题通过重发就解决了。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。