计算机网络—传输层

传输层服务

传输层的上一层是应用层,所以他应该是为应用层提供更好的服务。因此,传输层提供的是如何区分多个应用进程之间的标识问题,并且将到来的每一个数据传输到对应的应用进程,从而实现端到端的逻辑通信。(因为我们站在传输层角度来看传输就是逻辑上的传输,并不清楚交付到网络层之下的数据如何传输。)

  • 传输层的发送方:将数据切成多个报文段(segement),然后将报文段交付给下一层的网络层继续封装。
  • 传输层的接收方:将到来的多个报文段拼起来,然后根据在传输层上对数据封装时的标识协议,传送到对应的应用进程。

对于本层的理解
在传输层中,一个数据想要在不同应用进程之间能够标识并且正确的交付到上一层的应用层中对应的应用进程,我们在传输层就要对应的做一些标识手脚。

  • 既然数据送到了我们这里,就证明我们下面网络层完成了不同地方不同网段的传输了,我们不必操心这方面,我们现在的问题就是如何解决我们这个数据要传输到主机上哪一个应用进程中去。-------因此我们必须将该数据封装多一个目的端口号,到了对方主机或者到了我们这的时候我们就知道他这个数据的目的是哪里,我们的应用想要通信,本身在网络编程socket的时候就已经标识了本机的端口号,所以我们只要识别出该数据的目的端口号即可。(当然面向连接与面向无连接的时候对应封装的数据不同)
  • 说人话:发送方将数据切开,在数据头部加个重要的东西
    也是在传输层唯一标识符——目的端口号
    (说明:只是在传输层能够唯一标识,因为你能够传到对方的主机靠的不是传输层,而是下面的网络层之下的…)
  • 源端口号:从发送方来看因为你在你主机上也要标识你自己的端口,你这个数据是从哪个端口号发出的也要标识,然后另一个要加的头部就是对方的端口号就很清楚为啥了,你送的数据就是要到这个端口号。
  • 本层解决的问题:
  • 本层为应用层提供的最重要的两个协议:UDP,TCP
  • 网络层是社会,传输层是家庭

在这里鄙人一直在思考,到底接收方收到数据后,我传输层解封数据,将数据根据目的端口号传到对应的应用进程之后,这个源端口号有啥用?假如我是UDP无连接的协议,并且我都收到数据了,我要这源端口号有何用?

  • 最后我发现,假如说我使用UDP协议与另一个主机通信,这时候给我发送数据,我要回答的时候,这时候源端口号就用途大了,派上用场了,我能够通过与源端口号发送到对方的对应端口号上的应用进程上,这样就实现了通信(当然UDP是无连接的best effort功能)
    这仅仅只是涉及到UDP,TCP会做更多的事情,不仅仅添加了源端口号与目的端口来进行可靠通信。

多路复用与分用

  • 多路复用:在发送方进行多路复用,我理解的意思是在交付给网络层之前,你多个应用进程走的都是一条路,就是先在传输层进行对数据拆分多个segement,包装好本地序号与应用的端口号与目的地址等等,然后直接发送出去,叫做多路复用。复用一条路。
    问题来了就是,由于网路编程进行通信是使用socket,因此我们交付数据是根据socket进行交付然后才算递到对应的应用进程,所以这时候的任务变成了如何标识唯一socket,只有标识了唯一的socket就能够分用了。
  • 多路分用:(其实我更喜欢叫他多路分解)在接收方进行多路分用,我理解的意思是在交付给应用层之前,你发来的多个segment报文段,我根据对应的端口号分给我对应的应用进程,较多多路分用。多条路分用一条路。
    UDP与TCP实现的socket标识不一致
  • UDP多路分用-----使用二元组(目的IP地址,目的端口号)
  • TCP多路分用-----使用四元组(源IP地址,源端口号,目的IP地址,目的端口号)

说明:这里的二元组与四元组是用来标识socket套接字的,通过该唯一的套接字传到我们对应的应用进程,这里的不是说我在传输层的事情,涉及到IP地址,而IP是在网络层的,所以这里用了传输层与网络层的东西来唯一标识一个应用进程。
非常的苦恼,我研究了很久,发现其实不管是UDP还是TCP,其实都是有用五元组,除了上面的四个以外,还有一个就是协议号,用来标识你使用的协议。之所以这样提出,我的理解是因为五元组中,我们使用UDP的时候,仅仅使用了五元组中的(目的IP地址,目的端口号),所以我们唯一标识UDP的只要二元组即可。TCP同理。---------真是很折磨人,虽然我很佩服科学的严谨态度,但是对于我这种平平无奇的普通人理解起来还真是要不枉得费上一番周折。

在UDP中
我们通常是不管安全性可靠性的,这玩意就像一个渣男,你使用一个端口号可以给多个服务器发送数据或者发送请求让他们给你发送数据,你可以同时接收多个方向来的数据,因此在UDPsocket标识中,他只给了你两样东西去标识,就是(目的IP地址,目的端口号),数据到了接收方时候,直接就是了当的传输到应用层对应的端口号即可,然后如果你要应答过去,这时候就可以从五元组中取出对方的IP与端口号来标识要发送socket(上面应该五元组是啥说的很清楚了)。并且UDP是无连接的,言简意赅就是UDP不会和谁谁建立一个通道专门为两个人使用,而是以一种撒网的方式,想和谁说就和谁说。

  • 接收方:根据socket的目的端口号,将数据递到应用进程中对应的端口号。
    (切记,根据目的端口导向同意socket,也就是接收方的应用进程可以接受不同的人发来的数据)
  • 发送方:从五元组中取出对方携带过来的信息,即,源IP源端口号就能发送到对方手里。

在TCP中
学完UDP后学TCP就让我醍醐灌顶了,TCP是一对一的连接,在通信之前会很礼貌的进行问候,会向对方询问是否同意建立连接通道。(打电话就是一个TCP建立连接的过程),如果建立了连接,数据要交给应用进程的时候,就需要额外的标识了,因为这时候不希望其他人打扰两个人进行的通道通信(二人世界),所以需要俩人的IP地址(身份证号),因此有了四元组一说(源IP地址,源端口号,目的IP地址,目的端口号),学到这,我真是哭笑不得,感慨前辈的聪慧的同时又觉得太容易混淆概念了。

  • TCP发送数据前是要先建立连接:先确保俩人是看对眼的,之后才能一直保持联系。
  • 接收方:根据四元组唯一标识的socket传输数据到对应的应用进程即可。
    (根据唯一标识,也就是一个应用进程只有与之建立通信的才能导向该应用进程的socket)
  • 发送方:集齐四元组唯一标识socket后发送数据到对方手里即可完成二人世界。

(由于本层是属于本机的应用进程之间寻址问题,不涉及网络层怎么寻址问题,所以我们默认IP地址是已知的)

无连接传输协议(UDP)

User Datagram Protocol = [ UDP ]

  • Best Effort服务(尽力而为)
    何为尽力而为,即尽量保证数据的可靠性,安全性,有序性,不丢包,但优点很显著,就是速度快。

  • 无连接服务
    这个说法对我的理解来说很有疑点,首先不管什么数据传输,肯定是经过了连接才能进行相互传输数据的,这里的无连接说法我只能勉强理解成在传输层服务这里,在两个人由于某种神秘力量认识后,即能够互相通信后(但这个不属于打招呼建立连接),接收数据这一方可以随时离开,也就是所谓的无连接,你要走就走要,我一堆人和我连着呢。
    写到这突然发现UDP越说越像主播行为,其实事实就是这样,网络上的主播直播就是UDP协议,主播就是发送方,我们接收方可以随时离开,这就是我所理解的无连接,不用你特地告诉那个人我要离开了。
    不管是主播还是观众都希望直播时候能够流畅的观看体验,所以UDP正中下怀,直播正需要这种快协议,直播直播,面向公众的也就说明直播出去的一般不属于秘密的信息。
    (比较处于意外的是DNS居然也用UDP)
    研究的时候让我比较满意的回答是:假如有DNS的解析缓存之后,采用UDP是最好的,假如没有当然要用TCP,很显然DNS是有解析缓存这功能,解析好了就不用TCP特地去根服务器请求,再去一级二级,不然真的很慢,根服务器也会hold不住。因此我的困惑也就解决了。

  • UDP报文段
    (IP地址是属于网络层的所以这里看不到,得封装IP数据报的时候才有)
    来自哈尔滨工业大学PPT截图

UDP校验和

  • UDP校验和checksum
  • 总的来说就是将所有数据切开成16bit,按列排放,然后进行就和,如果进位就把进位当00000000 00000001再加一次,如此重复求出来的和再取反就是校验和
  • 验证:接收方接收到数据后将整个数据的内容进行16bit排好,然后求和取反码,若全为1则数据准确无误否则就代表该数据出错。
    在这里插入图片描述

可靠数据传输协议(Rdt)


停等协议


  • 1.0
    Rdt1.0中,在发送方,假设传输层向下层交付的操作叫做rdt_send,下层将我的数据数据发送是准确无误的。在接收方,假设网络层交付上给传输层的数据是准确无误的,然后传输层接受后调用rdt_rcv交付数据给应用层。(这样就是很理想状态的Rdt1.0可靠数据传输),说实话学到这,这rdt1.0理想得让人觉得不真实,很显然现实生活是不可能这样的。

  • 2.0
    从2.0开始就开始有停等协议
    在2.0中,考虑产生位错误的数据,在这种状态如何处理?
    这时候校验和就发挥作用了,能够发现是否出现位错误,那么现在应该考虑如何从错误中恢复。
    这时候很显然的一个办法就是重传,好了,重传办法找到了,但是我们要怎样告诉对方要重传呢,这又是一个问题。
    然后我想到的就是用一个协议字段告诉对方是否接收成功,那么我能想到前辈们肯定能想到,所以出现了一个名为AQR协议,实现确认重传机制,如果接收成功就发送ACK报文段给发送方,如果接受的数据有误,则发送一个NAK给发送方,发送方接收到NAK后就知道要重传了,这就解决了发现错误后,及时重传。

    • 接收方:只有一个状态,就是等待状态,一直等着发送方向我发送数据,如果收到数据并且正确则发送ACK给对方,否则发送NAK
    • 发送方:有两个状态:一、发送状态,二、等待状态。发送状态是发送数据,等待状态是等待对方发送来的报文是ACK还是NAK,然后才能进行下一步操作,ACK则进入发送新报文的状态,NAK就是重传上一个出现错误的数据。

    学到这我一直有一个困惑,既然信息能够错误损坏,那玩万一我发送的ACK也坏掉了咋整?!!而且这样等ACK来这网速岂不时慢的离谱?!

  • 2.1-2.2
    2.1: 很明显前辈们想到了我上面的问题,所以为了解决第一问题,怎么重传,重传哪一份呢?这时候就要给报文段编号了,编一个序号,当接收方接收到期望收到的报文段的时候就发送ACK,如果中途ACK坏掉了, 好像在2.1还没解决到。(其实是用超时)
    2.2: 还有一个问题就是在2.1状态中,既然能够用ACK确认是否正确接收了,NAK好像没有什么必要继续发送了,那么在2.2就是直接把NAK这玩意干掉了,只用ACK便可完成,因为当我们第二次接收到上一个ACK的时候就知道我们当前的数据出错了,因为对方一直只告诉我之间的ACK正确,而不是现在我发的数据的ACK,因此利用该特性我们可以直接去掉NAK,没必要增加负担。
    (解释:因为在2.1中,接收方只会发送正确接收的,并且最大序号的那一个ACK)

  • 3.0
    3.0考虑到,万一整个数据丢掉了,不知去处了,即中途ACK坏掉了,这时候接收方怎么办?
    这时候引入了一个很麻烦的并且也很有用的东西,就是定时器,接收方在等待一个指定的时间后,就自动视为对方发送的数据丢失了,发送一个ACK提醒对方我要接受数据给我重传一下。

    • 这时候我又思考一个问题:加入我数据其实没丢掉,只是路上遇到了某些特殊原因晚到了一点,但是你莫名其妙给我发送了ACK,我发送方岂不时又以为你没接收到重传一遍?这网络岂不时阻塞严重了?而且我等待的时间比发送的时间还要长,先不说发短信发消息了,就连送美团送快递都要嫌慢了。就是还没解决网络发送快慢问题。

前辈们肯定不会止步于此,当然我学到这时想到的解决办法就是:不停地发送数据,不要停,有错误了就在接收方记录下来错误的报文段,然后等对方发送完了我就把错误的信息段发送给对方,让他给我把这些数据重传一下。但是这样会造成接收方发送方不必要的高内存存储问题!所以很显然我这法子是个坏想法,毕竟电脑C盘变红是一件很可怕的事情。


滑动窗口协议(流水线机制)

滑动窗口,我第一次看到这个名词的时候非常蒙圈,我知道接下来肯定是要解决我上面提出的问题,但是我绞尽脑汁也想不出这玩意和我提出的问题有啥关联。

  • 滑动窗口:顾名思义窗口,并且会滑动的,在计算机中只能是收发数据的东西,还能是啥。
    • 前辈们想到这办法就是将发送的数据不仅仅限于只发送一个,能够发送一堆有序列的数据,而且接收方也应该是有一个窗口(窗口可以不一样大小,但肯定小的一方优先级大,因为我都装不下了还隔这给我发呢,我直接丢掉!)
    • 学到这我的异或就迎刃而解了,我一下就想到,滑动窗口就是发送方有一个发送窗口大小,只能发送窗口大小的数据,同理接收方只能接受他自己的窗口大小的数据。
  • 接收方:接收数据发送ACK,接收到一堆数据后,可以不用一个个ACK都发过去,可以发送序列号最高的那个ACK,目的就是告诉发送方:“老子把你最高的序列号的数据都接受了,你赶紧把后面的也发了吧,前面的数据都没错”。(当然前提是他的窗口还能够接受足够的数据)
  • 发送方:发送方把一系列有序数据发送过去后等待ACK,只发送最高序列号ACK往后的数据,比如接收到一个序列号10的ACK,那我就知道我应该发11往后的数据了,因为之前的都收到了。
    • 我的疑惑又来了。A:现在知道要重传了,假如我发了123456789序列号的数据过去,结果你给我回了一个2,你的意思是34接受失败吗,还是说2只有3~9之中只有一个出错了,我啥也不知道啊,那只能重传了从3开始到9重新给你传?还是有一个办法能够知道 错误的是哪一个序列号的数据?B:假如我有一次发送发发送的数据太多了,多到已经超过对方的接收的窗口大小,这时候完蛋了,对方肯定会丢掉后面的啊,因为已经装不下了,还隔这发呢?我想到的办法就是有没有一个公式能够计算出双方能够用的窗口大小?C:有没有一种可能不用每一个数据额序列号ACK都要接受一遍呢,比如我发了123456,我最后收到了5,能不能代表我发送的12345都成了,下面只需要重发一6即可,而不是我接收那么多ACK数据,反而好像有点浪费内存的意思了。
  • 总结:滑动窗口,一开始不明白意思,明白后更觉得这名字起得好,滑动窗口滑动窗口,生动形象,双方用窗口滑动进行数据传输,不仅能够发现错,检测是否丢包,还解决了网络快慢问题,不像停等协议那么耗时,信道利用率低的离谱。所以总的来说就是:两边有一个窗口,用来互相接受发送数据,发送方只要最低那个序列号数据被确认了,就往前滑动窗口(意思其实就是你都确认了,我这边丢掉了,别跟我再要重传了),然后发送方在窗口中空了一个位置,就多了一个可以发送的位置的数据等待应用层给我,如此流水线的循环。接收方只要连续的无误的数据接收到了,就直接法最高序列号的ACK告诉发送方比这个ACK序列号低的数据包含该ACK序列号的数据都接收到了,赶紧给我发新的来。

补:我是学完后面的GBN与SR协议上来补充的,下面GBN解决了上面所述的问题,复习的时候提醒自己别放弃,看下去会有答案的。

GBN(Go Back N协议)


GBN=后退N帧


  • 发送方:发送12456序列号数据,接受到13456,缺了一个2,不过这时候我的窗口往前滑动,因为1收到了滑动推到2号位置,卡在了2没收到,所以2不能继续向前滑动(我的内心OS:怎么办,要继续等吗,还是重传一个?万一是晚了点而已咋整),这时候GBN就采取了一个定时器,设置一个合理的定时器,超时就重传,不管你是不是慢来。后退N个帧意思就是这样,假如全ACK都没收到,即使我滑动窗口内可以发的数据都发出去了,没有收到ACK,都要给我后退回去全部重传。
    • 如何重传:这里GBN的重传机制是当收到一个最高的ACK序列号就默认该ACK序列号之前的都正确接收到了,但是由于该序列号往后的ACK迟迟没有到来,超时了才重传。
  • 接收方:收到数据发送ACK,然后等待下一个自己期望收到的数据,接收方在GBN中可以发送正确接收到数据的最高序列号的ACK,也就是说接收到一堆数据之后不用一个一个发ACK确认,只需要发连续正确的且在这连续确认正确的序列号中发送最大的ACK就行。
    • 特殊情况
      • 假如我收到连续两个相同的分组,在GBN中,直接将重复的分组丢弃掉 。(因为有可能是网络延迟导致ACK发到发送方那里比较慢,导致发送方以为没发送过来又重发一遍,所以接收方这边只需要直接丢弃掉即可)
    • 举例子:接收方收到了123456,但是789没有收到,又或者说接收方检测到7号有错位,这时候他只会发6 这个ACK,因为123456都是排好序且正确的,所以只需要发6号ACK告诉对方即可明白。
  • 总结: GBN发送方就是将滑动窗口的数据发过去,接收方接到一堆数据之后,一个个确认,直到突然出错,然后就发没有出错的,按顺序序列号最高的那个,这样来告诉对方这个序列号后面的你给我重传一遍。
  • 思考:我在想我举的这个栗子好像有更优解,假如说真的是7号错位了,但是89没有错,那岂不是白白浪费掉89数据,在发送方那边不是又得重新从789发送一遍,浪费了链路资源了,还会造成不必要的网络拥堵。我觉得把错误位数据记录下来,只告诉对方错误的数据并且发送方只发送错误位即可,这样不就省很多资源了?!

SR(Selective Reapeat协议)


首先要解决我上述问题,要加功能

  • 增加缓存功能,这样才能不用管按序确认,只要将所有到来的滑动窗口数据缓存下来慢慢确认,不对的就发给对方让他重传不对的那个即可。

目前我只想到这个办法。


SR=Select Repeat (选择重传)

  • 接收方:对个到来的数据进行单独确认
    • 设置缓存机制,将所有到来的数据进行缓存,有错则不把ACK发送过去,只告诉正确的ACK给对方不用重传,当整个滑动窗口OK无误了才把数据交付给上层应用。(解决了接送方重复收到正确的数据,只需要接收出错的数据了重传过来的数据即可)
    • 假如我收到连续重复分组,照样丢弃,再次发送该分组的ACK告诉对方(解决了我ACK丢失)
  • 发送方:只重传没有接收到的ACK的数据(解决了发送方重传正确的数据,不用重头到尾重传,只需要重传错误即可)
    • 对每一个数据设置定时器,超时则重传。
    • 一个一个的确认ACK,最低的序列号没确认则不滑动,未确认的ACK超时直接重传。

SR的缺陷:

  • 简而言之就是:
    • 接收方
      • 1:当接收方发送的ACK全丢
      • 2:当接收方发送的ACK迟到
    • 针对以上两种情况,发送方
      • 1:超时重传的时候 (没问题)
      • 2:没有超时,收到1序列号ACK,我滑动窗口到2,但是我发送的3数据丢掉了,这时候上一个分组的2ACK到了,但其实这个2ACK对应的是1才对,这就出错了。

这么一想这个缺陷好像问题好大!(还需要改进)

在这里插入图片描述

  • 改进
    将双方的滑动窗口大小调制合适的范围就不会出现这个问题了。
    Send方= N S N_S NS
    Receipt方= N R N_R NR
    K 为可用滑动窗口的序列号(即123序列号这样)
  • 一般来说双方的滑动窗口是一样大小的,所以K一般和滑动窗口大小一致。

记住: K是发送的序列号大小,滑动窗口大小与序列号大小是可以不一致的,比如说滑动窗口大小是10,序列号是5,可发的数据包是5个这样子,只是这些教书上方便理解都写成了相同的,不过这样也是比较好的,一般都是两边滑动窗口一样大小=2K-1
在这里插入图片描述
在这里插入图片描述

  • 思考:学完GBN和SR协议之后,我反而更加揪心,因为我觉得干嘛不将GBN的累计确认一堆ACK和SR的只重传错误位数据的这两个功能结合起来啊?!

有连接传输协议(TCP)

  • 点对点
    建立连接后这个连接只有通信双方,没有其他人能够介入。
  • 可靠的,按序的字节流传输
    可靠是说真正意义上的建立连接,说话只有两个人知道。按序字节流意思是在TCP段头中有一个序号是用数据中第一个字节的序号作为该发出去的整个数据的序号(如:我发送1000bit后再次发送500bit,那么第二次的500bit的序号是500,而不是2,因为是按照字节编号的)

TCP结合了GBN中的累计确认ACK和SR中的缓存机制

注意:这里的缓存在TCP中采用的是把乱序到达的并且是正确的报文段缓存下来,但是后序如何处理没有说,是留给开发者自己发挥的,意思是指官方并没有明确指出要怎么处理。

  • 不同点

    • 序列号:使用报文段中第一个字节作为序列号
    • ACKS:使用的是期望收到下一次字节的序号为ACK(TCP使用累计重传机制,意思是:我只发你期望收到的,不管你是否有收到,你先给我发你期望收到的ACK,然后我继续发窗口里面的,直到超时了,我去检查窗口里哪一个没收到ACK,就把那几个重传一遍)发送方也是,因为有缓存,所以收到重复数据的时候丢弃,只管发自己期望收到的就行。
  • 难点

    • 如何设置计时器?
      • 我的想法:设置一个比RTT大的时间(很简单朴实)
      • 前辈们想法:设置一个比RTT大的时间,不能过短也不能过长。
        • 如何获取稳定的RTT:
          加权平均,就是测量RTT,将拿到的测量值加权平均。然后拿到RTT后,再将计时器设置比这个大的,也就是加一个安全边界值。在这里插入图片描述
        • 如何设置边界值:(不懂,记不起来的时候问度娘)在这里插入图片描述
        • 最后设置计时器时间为:在这里插入图片描述
          重新理一下TCP思路
  • 发送方:

    • 1:应用层交付下来数据,然后传输层封装报文段,然后继续往下传
    • 2:开启计时器
    • 3:发送:123456789
    • 4:收到ACKs:12_4_678_(359没收到)
    • 5:
      • 假设还没超时,窗口还在继续发继续滑动,因为12收到了,可以滑动两个位置,然后继续收应用层交付下来的2个报文段。
      • 假设这时候定时器超时了,就开始检查到底哪一个没有收到ACK,然后就把那些没有收到的ACK报文段重发一遍。
      • 假设这时候没有超时,但是我连续收到三个序号为3的ACK,表示我序号3的数据丢失了 ,要重传3,。同理如果后面的59也连续收到的话也要重传,当然也有可能是晚点到而已。
  • 接受方:

    • 1:网络层交付上来的数据,解封装出来。
    • 2:假设窗口大小还能存,就把正确无误的数据缓存下来,然后发送期望收到的下一个报文段数据的ACK(注意:这里的意思是假如说对方发送了10bit,序列号是12,那我发送的ACK是10+12=22)。
    • 3:如果对方一直发送重复的数据,就直接丢到(因为有缓存)
  • 总结:好像和我想的差不多,区别就是TCP貌似没有使用GBN的累计重传那个机制,就是只返回最高序列号ACK的这操作,而是使用了都要确认,但是可以不卡住,你继续发数据的意思。只要超时就检查还没收到的ACK报文段,直接重传这些报文段即可。

TCP拥塞控制


问题提出:
如果发送方要发送的数据远远大于接收方的窗口了,这时候在发送之前要怎样告诉发送方这些信息?
如果接收方窗口已经满了,我要怎么告诉发送方别再给我发数据了?


  • 通过报文段头部字段里面写入信息高速发送方我还剩多少可以接受的空间

    • 发送方就会根据这些信息限制自己发送的数据大小
    • 我的疑惑:万一人家告诉你现在满了咋整?是一点都不发吗?不发了之后,对方又不给我应答咋整,因为在TCP中式发送方打招呼了才会有ACK回来。
  • 动态计算发送速率
    在这里插入图片描述
    我理解是,CongWin窗口大小除以RTT往返时间就是允许发送的数据速率,因为RTT就代表能够来回的时间了,就是起码能够让ACK回来并且我发送方能够从发送到接收ACK的时间。

  • 怎么动态调整:采取改变发送窗口大小。

    • 首先如何知道网络塞车了?
      • 1:当收到连续三个ACK
        因为这时候就可以说明网络拥堵了,我以为你的ACK丢掉了,其实没有,只是晚来了一点,所以这可以直接判断网络拥堵了。
      • 2:超时。
    • 网络一旦拥堵,窗口应该如何改变才是最合适的?
      • 加性增——乘性减
      • 慢启动——SS
  • 加性增——乘性减
    意思是:发送数据的时候,慢慢的把窗口加1个大小。当检测到出现loss拥堵的时候,立刻把发送的窗口大小减至现CongWin窗口大小的一半。

  • 慢启动——SS
    意思是:一开始的时候没有发生拥堵事件,窗口大小成指数型增长,就是不希望增长的很慢,因为有可能双方就允许接收很大的数据。

学到这我又很想把这俩玩意结合在一起

  • Threshold变量
    很明显前辈们肯定想到了我的问题,要把上面两个功能结合在一起,因此提出了Threshold变量。
    • 1:选一个Threshold变量代表窗口的瓶颈大小
    • 2:一开始发送数据的时候窗口从1开始慢启动——SS,也就是指数型增长。
    • 3:当没有收到loss事件(拥堵)的时候,继续增长,当窗口大小到了Threshold变量值的时候,开始以加性增了,不能再指数增加了。
    • 4:如果这时候发生了loss事件,直接把窗口大小调到从1开始,然后Threshold变为我原本窗口大小的一半作为瓶颈变量。
    • 5:继续上述步骤

我又觉得这玩意有问题,我为啥要直接把窗口减到1那么小,我只是稍稍拥堵了一下而已,就把我减这么低的速率,这体验感好差啊!

  • 当然我能想到的前辈们肯定已经解决了:
    • 判断网路拥堵是否严重即可。 如何判断?
      • 1:如果收到连续三个ACK,代表还能收数据,只是满了点,拥堵不是很严重
      • 2:如果timeout表明是网络瘫痪的感觉了,拥堵十分严重
  • 那么知道了网络拥堵是否严重的时候应该怎么做?
    • 1:如果三个ACK,网络不是很拥堵,这时候就把窗口大小CongWin和Threshold一样,减为原来窗口大小一半即可。(这会状态是加性增)
    • 2:如果timeout,就要直接减为1大小了,但是别担心,这时候肯定Threshold是大于你的窗口大小的,这会肯定是指数型增长。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

竹等寒

谢过道友支持,在下就却之不恭了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值