《计算机网络》课程笔记 (Ch03-运输层)

为运行在不同主机上的应用进程之间提供逻辑通信功能。

将应用层报文切分为块,然后加上运输层首部,形成报文段,交付给网络层。

多路复用与多路分解

将网络层提供的主机到主机交付服务延伸到进程到进程交付服务。利用的是端口。

每个报文段有(源端口,目的端口)字段指示报文段要交付的套接字。当一个网络应用程序运行时,必须为其分配一个端口号。套接字与进程之间不一定一一对应,有的进程可以拥有多个套接字。

UDP下无连接的多路复用与多路分解

标识为<目的IP,目的端口>。来、回的报文段会发生端口号的反转。

TCP下面向连接的多路复用与多路分解

标识为<源IP,源端口,目的IP,目的端口>。对同一个目的端口的连接(如HTTP的80),根据源IP进行区分。

无连接运输UDP

用户数据报协议,只是做了传输协议能够做的最少的工作。

报文段结构

UDP校验和

对UDP报文段中所有16比特字求和,求和时遇到任何溢出都回卷(溢出位加到最低位),然后全部取反运算。

接收方将受到的全部的比特字(包括校验和)一起相加。如果分组中无差错,则这个和将是1111 1111 1111 1111;如果有1个比特是0,则说明分组中出现了差错。

只提供差错检测,不提供差错恢复。

可靠传输原理

如何在不可靠的信道上实现可靠传输?

四个事件

  • rdt_send:上层调用,可靠发送
  • udt_send:该层调用,不可靠发送
  • rdt_rcv:该层调用,可靠接收
  • deliver_data:该层调用,将数据送往上层

RDT 1.0 - 完全可靠信道

没有比特错误,没有丢包。

RDT 2.0 - 比特差错信道

引入校验和用来检测比特差错。引入确认机制(ACK和NAK)作为接收方的反馈消息,发送方收到NAK后重传。ACK和NAK不出错。

RDT 2.1 - ACK / NAK本身会出错

如果ACK/NAK出错,那么发送者直接重传当前的分组。

问题是引入了冗余分组,接收者无法分辨当前接收的是新分组还是重传的分组。解决方案是给分组添加序号,接收者收到相同序号的分组则认为是重传。

RDT 2.2 - 无NAK

ACK带序号,表示对对应分组的确认。如果发送方收到的是对上一个分组的ACK,则表示接收方没有正确接收当前分组,需要进行重传。

RDT 3.0 - 比特差错且丢包信道

由于新增了丢包问题,因此在RDT2.2的基础上新增倒数定时器用于进行定时重传。

在send pkt后一段时间若未收到ACK(说明pkt丢失或ack丢失),则重传pkt。

可能带来的问题是提前重传(ack还在路上),需要设置合适的timeout时间。

流水线传输

RDT3.0是一个停等协议,故存在性能问题,我们希望可以不停等方式运行,即允许发送方发送多个分组而无需等待确认。这要求增加序号范围;发送方和接收方要缓存多个分组。

解决流水线传输的差错回复主要有以下两种方法:

回退N步(GBN)

流水线中未确认的分组数不能超过N,即维护一个大小为N的窗口,发未ack的必须小于等于N。

接收方采用累积确认ACK,即收到ACK x时,x及小于x的分组均ACK。 这也意味着,如果发送方发送了1、2、3,接收方只收到1、3,则不可ACK 3,只能ACK 1。当超时发生时,发送方重传所有发未ACK的分组。

选择重传(SR)

收发双方都维护一个长度为N的窗口。发送方的窗口左不能大于最早的发未ack,接收方的窗口左不能大于最早的期待但未收到,即所有pending中的分组都必须在窗口中。

相比GBN,发送方只重传那些它怀疑在接收方出错的分组,从而避免单个分组的出错引起大量分组的重传。但这样,每个分组逻辑上都要有单独的定时器。

接收方在收到乱序分组时不丢弃而是缓存。在一段时间后发送方定时器将发现没有对应ack,从而怀疑丢失,进行重传。接收方收到缺失分组后补齐交付上层

序号空间与窗口大小

窗口大小必须小于等于序号空间的一半。窗口大小过大会导致无法区分是新的分组还是之前重传的分组(序号空间已经轮完一轮)。

面向连接的运输TCP

基本介绍

特点:一对一,全双工(一端可同时收发),流水线,面向字节流,可靠传输。有流量控制和拥塞控制。

MSS(最大报文段长度(不含头部))限制了报文段的payload。

  • 序号SEQ:该报文段首字节在有序的字节流中的编号

  • 确认号ACK:期望从对方收到的下一个报文段首字节的序号

    • 累计确认策略:对于失序的报文段, ACK该报文段的序号

  • RTT估计

    超时重传的时间间隔必须大于RTT(往返时间,即报文段发出到确认的时间),因此估计RTT很重要。

    使用指数加权平均来更新RTT的估计值:EstRTT=(1-α)EstRTTold+αSampleRTT,α=0.125,SampleRTT为采样的RTT

    同时估计一个参数RTT偏差:DevRTT=(1-β)DevRTTold+β|SampleRTT-EstRTTold|,β=0.25来衡量RTT的波动

    这样就可以给出超时间隔Timeout=EstRTT+4DevRTT

  • 可靠数据传输实现

    使用滑动窗口、累计确认、单个重传定时器在超时或重复ACK时触发重传

    • 场景1:仅超时重传

      • 从上层应用接收数据,启动定时器(如果未启动)
      • 定时器超时时,重传引起超时的报文段(最早发出未确认),重启定时器
        • 超时后如何设置新的超时间隔?可以加倍。但当收到上层数据或ACK时,要重新按照公式计算。
      • 收到ACK时,进行累计确认;如果此时仍有未确认的,则重启定时器
    • 场景2:快速重传:超时或冗余ACK重传

      冗余ACK:接收方送来一个之前发送方确认过的ACK,表明该期望包没有收到

      快速重传的做法是收到3个冗余ACK就立即重传,不等待超时

流量控制

发送方太快可能淹没接收方,因此需要流量控制。(注意对比和拥塞控制的区别)

接收方维护变量接收窗口rwnd, 用于告诉发送方当前还有多少可用的缓存空间。发送方已发送未确认的数据量必须小于等于接收方当前的接收窗口,即LastByteSent-LastByteAcked≤rwnd。(全双工通信时,发送方同时是接收方,两端都需要维护rwnd)

连接管理

三次握手

流程:SYN x → ACK x+1, SYN y → ACK y+1

在这个过程中,完成了连接的建立和序列号的协商

四次挥手

流程:FIN x → ACK x+1 → FIN y → ACK y+1

ACK x+1后不立即FIN:发送残余数据

ACK y+1后不立即CLOSE,而是等2MSL:客户端发送的最后一个ACK可能丢失。假设丢失发生,则1MSL后,服务器因没收到ACK而重传FIN;又1MSL后,新FIN到达客户端,客户端重新执行ACK y+1。

TCP还设有一个保活计时器。客户端如果故障,服务器不能一直等。服务器每收到一次客户端的请求后都复位这个计时器。

拥塞控制

太多数据被发送到网络中, 网络来不及处理。表现是丢包和延迟。

拥塞控制站在网络角度,不同于流量控制的双方角度。

拥塞的代价

参数:λin - 分组到达速率;λout - 分组退出速率;R - 链路承载量

  • 网络拥塞的一种代价:当分组到达速率接近链路容量时,将经历较长的排队时延。

    2发2收,路由无限缓存,不重传。左图λout变平是因为超出的包全部丢掉了。

  • 网络拥塞的第二种代价:发送方必须重传以补偿因为缓存溢出而丢弃的分组。

    网络拥塞的第三种代价:发送方在遇到大时延时进行的不必要重传,导致路由器转发不必要的分组。

    路由有限缓存,重传超时分组(丢失或太慢的)。则即使λin=λout,若考虑丢包重传,则λin'=λin+λforloss>λout,将发生拥塞。

    理想情况下,若能区分且只重传丢失分组,则λout最终仍可到达R/2,即链路仍合理满载,因为相当于恰补足了丢失的部分,而没有多余的包。

    实际情况下,不能区分丢失分组和太慢分组,会多重传(不必要重传),则链路无法合理满载。

  • 网络拥塞的第四种代价:当分组被丢弃时,每个上游路由器用于转发该分组使用的传输容量最终浪费了。如果路由器R处理两条链路,其中一条超载,则另一条几乎不通。如果超载的这一条传输的数据在后级又被丢弃,则整个网络吞吐量将趋于0。

处理方法

端到端拥塞控制:让发送方根据感知到的网络拥塞,来调整发送数据的速率。

  • 如何感知拥塞?

    • 发生丢包事件(超时、冗余ACK)则网络拥塞
    • 正常收到未确认的ACK则网络正常
  • 如何限制发送速率?

    • 维护一个变量拥塞发送窗口cwnd
    • 约束LastByteSent-LastByteAcked≤min{cwnd, rwnd}
  • 用什么算法调整发送速率?

    • 基本思想

      • 加性增:每经过1RTT,cwnd扩大1MSS,直到发生丢包
      • 积性减:一旦发生丢包,cwnd减半
    • 具体方法

      • 慢启动:慢速率开始,指数级增长

        • cwnd=1MSS。每收到一个非冗余ACK,cwnd+=1,相当于每个RTT,cwnd*=2。

        • 当cwnd到达阈值ssthresh时,转入拥塞避免模式(线性增长)

        • 当发生超时时,修正阈值ssthresh=cwnd/2,cwnd=1MSS,重新慢启动

        • 当收到3个冗余ACK时,修正阈值ssthresh=cwnd/2,cwnd=ssthresh+3,转入快速恢复模式

      • 拥塞避免:加性增

        • 从慢启动转向拥塞避免的条件可以知道,进入拥塞避免状态时,cwnd≈上次拥塞时的一半,则此时还没有拥塞,但不能过激增加
        • 每个RTT,cwnd+=1
        • 当发生超时时,修正阈值ssthresh=cwnd/2,cwnd=1MSS,重新慢启动
        • 当收到3个冗余ACK时,修正阈值ssthresh=cwnd/2,cwnd=ssthresh+3,转入快速恢复模式
      • 快速恢复:报文段守恒

        • 每个冗余ACK(说明有一个报文段被端系统接收了),cwnd+=1
        • 当发生超时时,修正阈值ssthresh=cwnd/2,cwnd=1MSS,重新慢启动
        • 当收到新的ACK时,cwnd=ssthresh,转入拥塞避免模式

posted @ 2020-05-28 04:00  z0gSh1u  阅读(431)  评论(0编辑  收藏  举报