计算机网络(2)

2023.01.05

传输层

传输层服务和协议

  • 作用:传输层为应用程序提供逻辑通信(网络层实现主机的逻辑通信)
  • 位置:应用层与网络层之间,发送方将应用程序报文(message)分成传输层分组(segment)传递给网络层,接收方将数据段重组成报文传递到应用层。

    例: 两个家庭的14 (Ann)-14(Bill)个孩子传递信件
    应用层报文 = 信封上的字符
    进程 = 堂兄弟姐妹
    主机 = 家庭
    网络层协议 = 邮递员(邮政服务)
    传输层协议 = Ann 和 Bill

  • 协议:传输层协议运行在端系统中(不是在路由器中实现,路由器最多3层);

    TCP :面向字节流
    ①可靠数据传输(reliable data transfer):通过流量控制、序号、确认、定时器,确保TCP正确地、按序地将数据从发送进程交付给接收进程。使主机间不可靠的IP 变成 进程间可靠的数据传输服务。
    ②拥塞控制(congestion):防止任何一条TCP连接的流量过多
    ③流量控制( traffic control):可以调节TCP连接的发送端的发送速率
    ④建立连接
    UDP:面向数据报
    ①不可靠的无序交付、“尽力而为”的服务,不保证延迟、带宽
    只能提供数据交付和差错检查

2023.01.17

多路复用与多路分解

例如:1个HTTP进程,1个FTP进程,2个Telnet进程
在这里插入图片描述

  • 报文格式
    在这里插入图片描述
无连接的多路复用和多路分解
  • 端口号:
    ①创建UDP套接字时,可以由运输层自动地分配1024~65535的端口号,也可以自己指定特定的端口号(必须是唯一的可被使用的)
    ②若开发“周知协议”的服务器端,则必须分配对应的“周知协议”端口号
  • UDP套接字:
    ①每个进程都有UDP套接字和对应的端口号
    ②由二元组标识——目的IP,目的端口号
  • UDP报文格式:源端口号、目的端口号、其他首部字段、应用数据

    问:为什么创建UDP套接字不需要源端口号,报文段又会自动添加源端口号?
    答:报文段中的源端口号用作“返回地址”的一部分,当主机B返回给主机A信息时,通过在A到B的源端口号作为B到A的目的端口号。

  • 工作原理:

    假定在主机A中的一个进程具有UDP端口号19157,它发送数据给主机B的另一个端口号为46428的进程。
    主机A的运输层创建一个segment,其中包括:源端口号(19157)、目的端口号(46428)、2个其他值、应用程序数据。
    运输层将该segment传递到网络层,网络层将添加头部信息封装程IP数据报,然后尽力交付给主机B。
    主机B接受该报文段,由接受主机运输层检查该报文段的目的端口号(46428),然后将该segment交给端口号46428标识的套接字。
    若接受方UDP发现接收到的目的端口号不正确(应用进程不存在),则直接丢弃该报文,并由ICMP发送“端口不可达”的反馈报文

面向连接的多路复用与多路分解
  • TCP套接字:
    ①由四元组标识——(源IP,源端口号,目的IP地址,目的端口号)
    ②与UDP区别:
    • UDP只需2个参数确定接受进程,TCP必须4个参数
    • 在UDP中:尽管两个UDP报文段有不同的源IP地址和/或源端口号,但是相同的目的IP和目的端口号,那么这两个UDP报文段将通过相同的目的套接字被定向到相同的目的进程
    • 在TCP中:两个TCP报文段具有不同的源IP地址或源端口号,那么定向到两个不同的套节字

      问:为什么要区分 不同源IP相同源端口号、相同源IP不同源端口号、不同源IP不同源端口号
      IP标识主机,端口号标识进程;所以当端口号号相同但IP不同,仍可以确定目的套接字

  • web服务器与TCP
    • 连接套接字和进程之间并不总是一 一的关系
    • 高性能web服务器只使用一个进程,但是创建多个线程处理多个连接套接字
    • 持久HTTP,在整条连接持续期间,客户与服务器之间由同一个服务器套接字交换HTTP报文。
    • 非持久连接,每一对请求/响应都创建一个新的TCP连接并在随后关闭,影响服务器性能 !

无连接UDP

  • 特点:
    ① 只提供数据交付和差错检测,几乎直接等同于IP数据报
    ② 丢失报文、无序报文,在传输层不可靠(但是UDP可能实现可靠传输,通过在应用程序自身中建立可靠性机制完成)
    ③ 无连接,每个UDP数据段的处理独立于其他数据段

  • 优点:
    ①关于发送什么数据以及何时发送的应用层的控制更为精细

    采用UDP时,只要进程传递数据给UDP,那么UDP立即打包成UDP报文段,并立即将其传递给网络层。
    而TCP建立连接、拥塞控制、出错重传等机制使得交付时间不可靠。
    所以在实时应用程序中,要求最小的发送速率,不希望过分的延迟数据报的传送,能适当容忍数据报的丢失,不适合TCP,采用UDP。

    ②无需建立连接

    TCP3次握手才能开始传输数据,UDP直接开始,所以不存在建立连接的时延。(DNS使用UDP减少时延,HTTP使用TCP保证文本数据的安全可靠)

    ③无连接状态

    TCP需要维护端系统的连接状态,包括接受和发送缓存、拥塞控制参数以及序号与确认号参数。UDP不维护状态信息,不跟踪参数,所以某些特定应用的服务器运行在UDP时,支持更多的活跃用户。

    ④分组首部开销小

    每个TCP报文段都有20字节的首部开销,而UDP只有8字节

  • 应用:远程文件服务器、流媒体、实时视频会议互联网电话、网络管理、DNS

  • UDP首部:源端口号(2B)、目的端口号(2B)、长度(2B)、检验和(2B),共8字节

    • 长度:整个UDP报文的字节数,单位为 B字节,
    • 检验和:接收方使用检验和判断传输是否有差错,但是无法实现纠正差错!
  • UDP检验和

    • 伪首部:不是真正的物理存在,不向下传送也不向上递交,只是方便计算校验和
      在这里插入图片描述 在这里插入图片描述

    • 发送方的UDP对报文段中伪首部、首部(初始化检验和字段全为0)、数据,按16bit求和(高位溢出,回卷加到最低位),最后取反码。得到16bit的检验和。

    • 接收方的UDP计算报文段中的伪首部、首部、数据(不足一字节的补0)全部按16bit求和,并取反码。若反码结果最后为0,则正确;反之,传输出错。

    • 端到端原则:某些功能必须基于端到端实现,与在较高级别提高这些功能相比,在较低级别实现可能时多余的或没有价值的。UDP通过校验和实现差错检测;而许多链路层协议通过奇偶校验、循环冗余校验等,但不能确保所有经过的链路都提供了差错检测协议且即使报文在链路正确传输,在路由器内存中也可能引入比特差错。

2023.01.18

可靠数据传输原理

  • 可靠数据传输协议(reliable data transfer protocol,rdt):数据通过一条可靠的信道进行传输,其下层协议可能不可靠(IP、链路)
  • 服务框架:
    在这里插入图片描述
  • 四个接口:
    在这里插入图片描述

构造可靠数据传输协议

完全可靠信道的可靠数据传输—rdt1.0
  • 特点:
    ①底层信道已经是完全可靠的,不存在bit错误,不存在分组丢失
    ②发送方和接收方的FSM独立,都只有一个状态,事件发生后状态回到自身
    ③由于可靠传输,接收方不需要发送反馈信息给接收方
  • 有限状态机(Finite-State Machine,FSM):
    • 箭头:指示协议从一个状态变迁到另一状态
    • 横线上方:触发事件,若无则用 ‘∧’
    • 横线下方:事件发生时所采取的动作,若无则用 ‘∧’
    • 初始状态:用虚线标识
  • rdt1.0有限状态机
    • 发送方:应用层的过程调用产生rdt_send(data),传输层发送方通过rdt_send(data)事件接受应用层的数据,然后使用make_pkt(data)动作产生一个包含该数据的分组(packet),最后使用udt_send(packet)动作将分组发送到信道。
    • 接收方:rdt通过rdt_rcv(packet)事件从底层信道接收到分组,然后使用extract(packet,data)动作从分组中取出数据,最后使用deliver_data(data)动作将数据向上递交给应用层。
      在这里插入图片描述
具有bit差错信道的可靠数据传输—rdt2.0
  • 特点:
    ①下层信道可能让传输分组中的bit受损,常出现在网络的物理部件中
    ②提供新机制处理bit差错:差错检测、接收方反馈、重传
  • 自动重传请求协议(Automatic Repeat reQuest,ARQ)
    ①基于重传机制的可靠数据传输协议,使用肯定确认、否定确认的控制报文
    ②差错检测:接收方需要检测何时出现了bit差错(UDP的校验和),并可能纠正分组中的bit差错;rdt2.0分组检验和字段
    ③接收方反馈:发送方想确定接收方的分组情况是否被正确接收,接收方使用“肯定确认(positive ackowledgment,ACK)”或“否定确认(negative ackowledement,NAK)”的分组,理论上这些分组只需1bit,0表示NAK,1表示ACK
    ④重传:发送方直到接收方的NAK后,重传该分组
  • rdt2.0有限状态机
    • 发送方:两个状态;左边状态表示rdt等待rdt_send(data)事件接受数据,然后用make_pkt(data,checksum)动作产生分组,最后通过udt_send(sndpkt)动作将分组交给底层。当状态不是“等待来自上层的调用”时,rdt不会接受新的数据,即此时不可能再发生rdt_send(data)。右边的状态存在两个事件;发送方若收到ACK分组的rdt_rcv(rcvpkt) && isACK(rcvpkt)事件,则返回到“等待来自上层的调用”的状态。若收到NAK分组rdt_rcv(rcvpkt) && isNAK(rcvpkt)事件,则重新产生udt_sed(sndpkt)动作,继续停留在该等待状态。

    • 接收方:单一状态;两种事件,若接收方接受分组并判断出无差错则触发rdt_rcv(rcvpkt) && corrupt(rcvpkt)事件,则产生udt_send(NAK)动作将NAK分组反馈给发送方;反之触发rdt_rcv(rcvpkt) && notcorrupt(rcvpkt)事件,产生extract(rcvpkt,data)动作取出数据,然后产生deliver_data(data)动作将数据递交给应用层,最后使用udt_send(ACK)动作将ACK分组反馈。
      在这里插入图片描述

    • 停等协议:发送方将不会发送一块新数据,除非发送方确信接受已正确收到当前分组。

    • 问题:ACK/NAK分组也存在着受损

      • 第一种可能:以口述报文为例,如果发送方不理解接收方的“OK”或“请再说一遍”,发送方可能会问“你在说什么?”(引入一种新分组)。而接收方可能复述“你在说什么?”,也可能因为“你在说什么?”分组出错而不知道这个分组是原本口述内容的一部分还是一个要求接收方再次重复上次回答的请求。显然,问题将会越来越复杂
      • 第二种可能:增加足够的检验和bit,使得发送方可以检测差错,恢复差错!以便确认ACK/NAK分组
      • 第三种可能:只要发送方收到不清楚的ACK/NAK分组时,就重传当前数据分组,由此引入冗余分组

        duplicate packet,根本困难在于接收方不知道它上次发送的ACK/NAK分组是否被接收方正确接受。所以它无法事先知道收到的分组是新的还是一次重传!

    • 冗余分组解决方案:发送方在数据分组中添加一个新字段进行编号;接收方通过编号判断收到的分组是否是一次重传。若是重传,则接受方丢弃冗余分组。(几乎所有现有的数据传输协议中,包括TCP都采用了这种方法)

2023.01.19

具有数据分组序号的改进版2.0—rdt2.1
  • 特点:
    ①发送方为数据分组增加编号,1bit的(0/1)即可
    ②发送方必须检查是否收到混淆的ACK/NAK
    ③发送方和接收方的状态数量都加倍
    ④接受方必须检查是否收到重复报文
    ⑤接受方不知道它发出的上一个ACK/NAK是否被正确接收

  • rdt2.1发送方FSM:四个状态;

    • 首先rdt2.1处于状态“等待来自上层的调用 0”,触发rdt_send(data)事件,产生make_pkt(0,data,checksum)动作对数据分组,然后使用udt_send(sndpkt)动作将分组向下传递给网络层。状态转向 “等待ACK/NAK 0”
    • 发送方判断接收方的ACK/NAK分组。首先使用rdt_rcv(rcvpkt)动作接收分组并使用corrupt(rcvpkt)动作isNAK(rcvpkt)动作判断(该数据是否损坏或为NAK分组两者之一),然后产生udt_send(sndpkt)动作重传发送方上次发出的数据分组。“状态保持不变”;若发送方根据notcorrupt(rcvpkt)动作isACK(rcvpkt)动作判断出(数据没有损坏并且为ACK分组),则直接转向 “等待来自上层的调用 1”
    • 产生rdt_send(data)动作后,产生make_pkt(1,data,checksum)动作对数据分组,然后用udt_send(sndpkt)动作将分组向下传递给网络层。状态转向 “等待ACK/NAK 1”
    • 发送方判断接收方的ACK/NAK分组。首先使用rdt_rcv(rcvpkt)动作接受分组,使用corrupt(rcvpkt)动作isNAK(rcvpkt)动作判断(该数据是否损坏或者是NAK分组两者之一),然后产生rdt_send(sndpkt)动作重传发送方上次发出的数据分组。“状态保持不变”;若发送方根据notcorrupt(rcvpkt)动作isACK(rcvpkt)动作判断出(数据没有损坏并且为ACK分组),则直接转向 “等待来自上层的调用 0”
      在这里插入图片描述
  • rdt2.1接收方FSM:两个状态;

    • 接收方处于 “等待来自下层的 0”状态,该状态处理三种事件。
      • 第一:使用rdt_rcv(rcvpkt)动作接收分组,再使用notcorrupt(rcvpkt)动作has_seq0(rcvpkt)动作判断(分组0没损坏且为预期0号分组),则数据分组正确无误,使用extract(rcvpkt,data)动作取出数据,使用deliver_data(data)动作将数据递交给应用层,然后接收方还要使用make_pkt(ACK,chksum)动作打包一个ACK分组,最后使用udt_send(sndpkt)动作将ACK分组返回给发送方;状态转向 “等待来自下层的 1”
      • 第二:使用rdt_rcv(rcvpkt)动作接收分组,再使用corrupt(rcvpkt)动作判断(数据损坏),则产生make_pkt(NAK,chksum)动作打包一个NAK分组,最后用udt_send(sndpkt)动作将NAK分组返回给发送方;“状态保持不变”
      • 第三:使用rdt_rcv(rcvpkt)动作接收分组,再用not_corrupt(rcvpkt)动作has_seq1(rcvpkt)动作判断(数据分组0没有损坏但收到1号分组),则产生make_pkt(ACK,chksum)动作打包ACK分组,最后使用udt_send(sndpkt)动作将ACK分组返回给发送方。“状态保持不变”
    • 接受方处于 “等待来在下层的 1”状态,该状态也处理三种事件。
      • 第一: 使用rdt_rcv(rcvpkt)动作接收分组,并使用corrupt(rcvpkt)动作判断(分组1损坏),则产生make_pkt(NAK,checksum)动作打包一个NAK分组,最后使用udt_send(sndpkkt)动作将NAK分组返回给发送方。“状态保持不变”
      • 第二: 使用rdt_rcv(rcvpkt)动作接收分组,并使用notcorrupt(rcvpkt)动作has_seq0(rcvpkt)动作判断(分组1没损坏但是收到与预期不符的0号分组),则产生make_pkt(ACK,chksum)动作打包一个ACK分组,最后使用udt_send(sndpkt)动作将ACK分组返回给发送方。“状态保持不变”
      • 第三:使用rdt_rcv(rcvpkt)动作接收分组,并使用notcorrupt(rcvpkt)动作和has_seq1(rcvpkt)动作判断(分组1没损坏且收到预期的1号分组),则产生extract(rcvpkt,data)动作取出数据,再使用deliver_data(data)动作将数据递交给应用层,然后接收方还要产生make_pkt(ACK,chesum)动作打包ACK分组,最后使用udt_send(sndpkt)动作将ACK分组返回给发送方,状态转向 “等待来自下层的 0”
        在这里插入图片描述
有bit错误的信道上无NAK的可靠传输协议—rdt2.2
  • 特点:
    ①功能和rdt2.1相同,但只有ACK
    ②接收方的make_pkt(ACK,0|1,checksum)中增加了此次被确认的报文序号
    ③发送方收到重复ACK 时和原来的NAK一样,重传上次数据分组
  • rdt2.2FSM
    • 发送方:在这里插入图片描述
    • 接收方:
      在这里插入图片描述
具有bit差错和丢包的信道的可靠数据传输(比特交替协议alter-nating-bit protocal)—rdt3.0
  • 引入:假设底层信道存在 bit差错和报文丢失(数据或ACKs)

  • 新问题:怎么检测丢包、丢包后的处理

  • 解决方案:

    • 检测丢包:倒计时定时器
    • 丢包后的处理:检验和、序号、ACK分组、重传等
  • 理解:发送方等待“合理的”确认时间,即至少等待:一个分组的往返时延RTT + 接收方处理一个分组的时间。如果在这个时间段内发送没有收到ACK(数据分组丢失、ACK丢失、都没有丢失),都是重传该分组。

  • 倒计时定时器(countdown timer):实现基于时间的重传机制,在给定的时间到期后,中断发送方。所发送方应该具有3种功能:①每发送一个分组时,启动定时器②响应定时器中断③终止定时器

  • rdt3.0FSM

    • 发送方: 在这里插入图片描述
    • 接收方: 在这里插入图片描述
  • rdt3.0的操作

    • 无丢包操作:
      发送方发送分组0,接收方接收分组0并发送ACK分组0,发送方接收ACK分组0,至此分组0传输完毕,依此类推。

    • 分组丢失(丢包):
      发送方发送分组1但中途丢失,在适当时间内发送方没能收到接收方的ACK1,触发超时重传。发送方重新发送分组1,接收方接收分组1并发送ACK分组1,发送方接收到ACK分组1,至此丢失后的分组1重传成功。
      在这里插入图片描述

    • 丢失ACK:
      发送方发送分组1,接收方接收分组1但接收方发出的ACK1中途丢失,导致发送方在适当的时间内没能收到ACK1,触发超时重传(产生冗余分组1,删除多余的只保留一个分组1)。发送方重发分组1……

    • 过早超时:
      发送方发送分组1,接收方接收分组1并发送ACK1,但是ACK1时间太长超过适当的时间,触发重传,发送方立即重发分组1。当第一个ACK1到达发送方,发送方发送分组0,接受方接收分组0并发送ACK0。当第二个因为重发分组1产生的ACK1到达时,发送方什么也不做。 等待真正的ACK0。
      在这里插入图片描述

  • 性能评价:rdt3.0是正确的协议,但性能不足,由于停等协议。

    例如:1Gbps链路,30msRTT,1KB的报文,计算网络利用率
    发送时间:(1000*8)bit/pkt ➗ 10^9 bit/s = 0.008ms/pkt
    总时间:0.008+30 =30.008ms
    利用率:0.008 ➗ 30.008 =0.27 %
    理解:发送方实际将分组送入信道的那部分时间占发送时间的非常非常小,利用率极低。若实际中考虑其他额外时延,将会更为严重!


2023.01.26

流水线可靠数据传输协议

  • 定义:不以停等方式进行分组传送,允许发送方向接收方连续发送多个分组而无需等待确认。
  • 技术支持:
    • 增加序号范围:因为每个分组都必须有一个唯一序号,用于ACK确认
    • 缓冲分组:发送方和接收方都需要设置缓冲,以便分组的发送和确认
    • 差错恢复:回退N步(GO-Back-N,GBN)、选择重传(Selective Repeat,SR)
回退N步(GBN)——滑动窗口协议
  • 理解:允许发送方发送多个分组而不需等待确认,但它受限于在流水线中未确认的分组数不能超多某个最大允许数N
  • 滑动窗口:在一个长度为N的序号范围内的窗口,表示已经发送但还未被确认的分组的许可范围

    问:为什么限制窗口大小N?
    答:流量控制、拥塞控制等。
    问:GBN的滑动窗口的大小是固定的吗?
    答:错误,不固定大小,但 ≤(2^N)-1
    问:假设发送方已经发送了0~7的帧,当计时器超时时,若发送方只收到0、2、3号帧的确认,则发送方需要重发的帧数是多少?分别是哪几个帧?
    答:根据最大接收的ACK3,可知窗口大小为4,GBN协议的确认是累积确认,所以需要重发的帧数是4个,依次为4、5、6、7号帧。

  • GBN的序号范围:

    基序号base:最早未确认分组的序号 &nbsp&nbsp&nbsp下一个序号nextseqnum:最小的未被使用序号
    [0 ~ base-1]:表示已经发送并收到ACK确认的分组
    [base ~ nextseqnum-1]:表示已经发送但未收到ACK确认的分组
    [nextseqnum ~ base+N-1]:表示如果还有上层数据,还可以用于发送分组的序号
    [base+N ~  >>>]:不能使用,直到序号为base的分组已经完成确认
    在这里插入图片描述

  • 使用原则:分组的序号在分组首部的固定长度为K的字段,表示有限的序号范围,所有涉及序号的运算都必须使用模2^k运算。
  • GBN发送方:
    • 响应上层调用:响应上层的rdt_send()并检查窗口n是否满足分组序号
    • 接收ACK(n):确认所有n以前的分组及序号为n的分组——累积确认ACK
    • 超时事件:使用定时器用于恢复数据或确认分组的丢失。只有一个定时器记录序号为base的时间。如果出现超时,发送方将重传所有已发送但还未被确认的分组(base~base+N-1)。
  • GBN接收方:
    • 维护的预期n号分组并正确接收:若上次接收到n-1号,此次接收到n号,则接收方发送ACKn,并将数据递交给应用层。所以一旦分组n被接收并递交,则所有序号比k小的分组都也已经交付。
    • 其他所有情况:接收方丢弃当前分组,并对最近按序接收的分组重新发送ACK。
  • GBN协议运行图:

    窗口大小为4,首先发送分组0~3,然后由于窗口限制,必须等待一个或多个分组被确认。接收方接收到连续分组0、1后,窗口便向前滑动,发送方继续发送4、5。但是接收方发现分组2丢失,此时窗口内的3、4、5分组失序到达,分组3、4、5被丢弃并发送最后一个正确接收分组1的ACK1。直到达到适当的时间,触发超时重传,重新发送分组2、3、4、5,并依次反馈ACK2、ACK3…
    在这里插入图片描述

  • GBN缺陷:分组丢失时,存在着不必要的重传,导致性能较差
选择重传协议(SR)
  • 定义:选择性重传在接收方丢失或受损的分组,不再重传不必要的(尽管失序)的正确分组,失序的分组将被缓存直到所有所有丢失的分组被重新接收。

  • 发送方:

    • 响应上层调用:接收上层的rdt_send()调用,并检查分组序号是否位于窗口内。若在,则打包;否则,缓存数据
    • 超时(n):每个分组都必须有自己的逻辑定时器,重发分组n,重启定时器
    • 收到ACK(n):若n在窗口内,则标记该分组n为已接受。若分组n刚好等于send_base,则窗口base向前移动,并且在窗口内的未发送分组将发送。
  • 接受方:

    • 序号在[rcv_base ~ rcv_base+N-1]内的分组被正确接收:正确接收,反馈ACKn。其中若该分组n为失序分组,则缓存该分组;若该分组n刚好等于rcv_base,则说明该分组及以前缓存的序号连续,都将被接收并向上递交。
    • 序号在[rcv_base-N,rcv_base- 1]内的分组被正确接收:反馈ACKn,即使该分组曾接收过。
    • 其他:忽略该分组。
  • SR窗口序号:SR的发送方和接收方的窗口不总是同步一致的
    在这里插入图片描述

  • SR协议运行图:

发送方和接收方窗口大小都为4。发送方发送0、1分组,接收方接收分组0、1并反馈ACK0、ACK1,向上递交分组0、1的数据,接收方窗口向前滑动。发送方发送分组2、3,接收方发现分组2丢失,但接收方接收到分组3,接收方缓存分组3,反馈ACK3。当发送方已知分组0、1已被接收后,窗口才向前滑动,发送分组4、5,接收方接受到分组4、5后,缓存并反馈ACK4、ACK5。当分组2的计时器超时后,重发分组2,此时分组2、3、4、 5在接收方都被缓存,可以直接向上递交给应用层,接收方窗口向前滑动。
注意:
①发送方的窗口移动时机:在收到接收方的ACK时
②接收方的窗口移动时机:在收到预期分组或连续缓存的分组时
在这里插入图片描述

  • SR缺陷:不能区分一个新分组和一次重传
    序号空间大小:4,K = 2
    窗口大小:3
    问题:当窗口大小比序号空间大小小1时,SR协议不能正确工作
    限制:窗口长度必须 ≤ 序号空间大小的一半 (或者 Ns +Nr ≤ 2^K)

可靠数据传输机制总结

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值