TCP基础(1)

TCP基础(1)

好了,今年的区域赛全部打完了,回来思考了一周的人生。有空写一个总结。
但是思考人生的结果就是:比赛还得继续打,后边的计划也得开始了。
回来就投了几个简历,也收到了面试邀请,所以需要把前边的基础给复习一下。首先肯定是网络基础了。就从TCP开始吧,在TCP前边的HTTP,UDP,DNS啥玩意的,基本上还记得。那些东西的设计都是很自然的。

UDP的限制

UDP是一种尽力而为的服务,它尽力的发包,但是不保证正确,不保证能到达,不保证重复…
所以它一无是处?NONONO,效率高是它的很大的优点。并且有的数据并不需要很精确,时不时丢几个包问题也不大(比如看电视?少个几帧也问题不大,并且现在的技术,可以很大程度的把少的数据给补上)。所以需求决定了好坏,没有固定的答案。
那么,什么是可靠传输?

可靠传输

这是一个无法被准确定义的概念,可以说满足需求的传输就是可靠传输,但是需求千千万。但是,一个可靠的传输基本上都要满足一下几点:
(1)收到的包不会重复
(2)收到的包顺序不会乱
(3)延时重发保证所有的数据包都能到达
(4)收到的包是准确的,或者说出错了之后会有重发机制。

单个包的可靠传输

既然UDP无法进行可靠的传输,那么就需要对它操作一波,让它可靠起来。首先考虑单个包怎么可靠的传输。
1.正确性:发送端发送包过来,如何保证这个包的内容是正确的?其实这个问题是最容易解决的,对包做一个Hash,这个东西也叫做包的校验值,两端使用的hash算法都是一样的,发送的时候给包的这个字段打上标记,接收端验证即可。
2.丢包重发:如果某个包丢了,那么这个包怎么重发呢?首先,接收端不知道发送端发过了,发送端也不知道接收端没有收到。这就很尴尬了。一种解决方案是:接收端在收到每一个包时,会发送一个ACK字段个发送端,发送端接收到了这个ACK,就知道了包成功到达。否则呢??重发么,万一那个ACK包丢失了怎么办?这时候其实接收端已经收到了,但是发给发送端的ACK又丢了。这个时候,发送端其实再发一次无所谓,因为就算是接收端接收到了两个同样的包,它可以知道要哪个,这个后边再说,但是发送端什么时候发就成了问题。这里就是RTT的概念了,考虑一个包在网络传输上的最长时间,RTT表示一个包从一来一回的时间,如果在RTT内,接收端还没有接收到ACK包,可以认为丢包了。那么接收端不管这么多,就再把包发一遍
3.重复包:处理重复包的方法有很多,可以直接丢弃,也可以根据时间来选择最新的那个。但是这里面也有很多的问题,就不考虑这么多了,就按照遇到重复的包直接丢弃算。

多个包的可靠传输

在上面的讨论中,使用了三种避免不可靠的方式,当然了还有很多的问题,开头就说了,没有一个准确的可靠传输的概念,这里只是提了一下大多数场景中需要满足的需求。但是那只是单个包,每次传输一个包效率太低,并且浪费带宽。就像修了一条高速公路上每次只有两辆车在跑(发送端给接收端的数据包,接收端给发送端的应答包)这是十分的浪费资源的。
那么一次发多个包会出现什么问题呢?又该如何解决?

基于滑动窗口的多包传输方案

滑动窗口这个概念,ACM里面是有的,比如很经典的滑窗求区间最值。但是这里是计网啊,不需要求区间最值,但是这两个东西的思想是一样的,都是来源于生活中的滑动窗口。

  1. 这是个什么东西:还是普及一下滑动窗口额概念
    2滑动窗口开始时,一个大小为3的窗口位于起点,然后可以把它向右滑动一下:
    在这里插入图片描述然后窗口就到了2-4这个区间。滑动窗口就是一个窗口,所有在窗口内部的数据时可见的,所有不在窗口内部的数据时不可见的。
    2.怎么用:
    (1)假设数据已经被打包成了一个一个的数据包,从1开始排列开来,那么首先设置一个大小为W的窗口,一次先把这W个数据包全部发出去。发出去之后,这个时候窗口不能滑动,而是等待应答
    (2)接收端接受到包之后,注意,这里可能会乱序。但是接收端会重排这些数据包,然后给发送端应答。这里假设一切都很好,没有丢包以及错误等。那么接收端接收到第一个包之后,就给发送端发送ACK 1,表示接收到第一个数据包。这个时候,接收端发现1号包安全准确达到,就开始滑动窗口,然后发送第W+1个包,这样依次把所有的包发完。

窗口大小的设计

使用滑窗时,窗口大小很重要。太大容易造成拥塞,太小浪费带宽。所以合适的大小基本上满足这个公式:
在这里插入图片描述
RTT就是上文提到的RTT,B是带宽,W窗口大小。关于W的设计,取决于RTT和包的大小,这两个参数,是可以动态变化的,后边详细说。

一些问题

当接收端接收到包时候,可以给发送端发送应答包,但是一旦包错误了,比如发送1,2,3,4,5这五个包,3号包丢失了,成了1,2,4,5.那么接收端如何告诉发送端3号包丢失了,并且把三号给传过来呢?这就是应答方案的设计。
当然了,ACK包也是可能丢失的,如果ACK丢失了,那么我们就假定这个包丢失了,这样发送端还是会重传,得到了重复包。重复包可以丢弃,这个可以不考虑。

三种应答方式

接收端如何告诉发送端丢包了呢?
(1)单包应答:这个就是我们刚才的例子,其实很容易想到,在当前窗口内的包,假设在RTT内没有收到应答包,我就把没有ACK包重发一遍。
(2)累加应答:还是发送1,2,3,4,5.假设3丢失,那么ACK序列1,2,2,2,2.表示其实我当前只收到了2号以及之前的包,那么发送端一看就明白了,3号丢失了。就重传3号包或者把3号之后的包全部传了,所以也叫GO_BACK_N。但是其实这里是存在一些问题的,因为4,5已经到了,没必要传输4,5.
(3)完全应答:依旧是上述,3号丢失,那么应答序列可以是这样:
1
2
2
2,4
2,4,5
把已经收到了包附加在后边,并且窗口也不再滑动,说明3号丢失,那么我只传3号,并且4,5不需要传。这样其实就可以避免了一些已经收到了的数据的传输。
那么这种凡是看起来很棒,问题呢?其实也很明显,因为需要传输的数据多了,这些字段都需要存在传输的数据里。那么如果很多的情况下,其实也是浪费了一些不必要的资源。
以上就是一些应答的方式,似乎也没有好坏之分。

窗口大小的调整

如果丢包严重,很大的原因是因为窗口大小不是很合理,因为你一次发的数据太多了,很多数据都没法到达,所以就需要调整窗口大小,少发一点。
一种调整的策略:AIMD:(ADD Increase Multiply Decrease).和式增加,积式减少。具体操作就是:当前窗口大小是W,那么当丢包一次W=W/2,成功发送,W=W+1.
基本上就是这些了,这是TCP能实现可靠传输的基础,当然了TCP还远不止这些。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值