计算机网络:传输层

传输层

传输层协议在端系统中实现而不是路由器,简单起见把运输层分组称为报文段网络层分组称为数据报

UDP,TCP的基本责任将两个端系统间IP的交付服务拓展到端系统上两个进程之间的交付服务

将主机间交付扩展到进程间交付被称为运输层的多路复用与多路解复用

多路复用与多路解复用

  • 多路复用:从源主机不同套接字收集数据块,并为每个数据块封装上首部信息生成报文段,报文段投递到网络层
  • 多路解复用:将传输层报文段的数据交付到正确的套接字

UDP

报文

image-20230905130551078

端口号:通过端口号目的主机可以实现多路解复用

长度:UDP报文中的字节数(UDP 报文头和 UDP 数据长度)

校验值:检验数据在传输过程中是否被损坏,RFC中标准要求,发送端应该计算检验和,接收端可选

  • 发送方:对报文段的所有16bit字的和进行反码运算,其中和的溢出都被回卷(把进位加上,如三bit数 110+011=010),得到的结果就是校验值
  • 接收方:算出报文段的所有16bit字外加校验码的和,同样溢出都被回卷,结果是1111 1111 1111 1111则数据完整

残存错误:这种检错是有限的,会出现有些数据错误但是得到的校验和是正确的情况,叫做残存错误

可靠数据传输原理

  • 假设信道保证发送分组,不丢失分组,且分组按照发送顺序被接收,但是分组数据可能受损

    简单的解决办法

    发送方发送完一个分组后等待,接收方通过校验和来确认分组完整性,完整则回复肯定确定(Positive Acknowledgment,ACK)分组通知发送方发送下一个分组,否则发送否定确定(Negative Acknowledgment,NCK)分组通知发送方重传当前分组

    新的问题:ack/nck出错怎么办?

    给ack/nck加上校验和,给分组加个序号字段,发送方收到的反馈分组ack/nck出错时,不管三七二十一,都重传分组,接收方根据分组序号和上次分组的序号比较结果来反馈发送方,如果接收到的序号和等待的序号不一样,证明ack/nck分组出错了,只需要重传个ACK,并丢弃掉这个分组即可

    不使用nck

    接收端在接收到错误分组不发送 NAK, 而是对上次正确接收的分组发送一个ACK,发送方接收到对同一个分组的两个ACK就知道没有正确发送该ack分组的下一个分组

    比如我们现在要传输p0 p1 p2 三个分组,接收方接收到正确的p0后发送ACK 0表示正确接收p0,发送方继续发送p1,如果接收方正确接收p1,发送ACK 1表示正确接收,否则发送ACK 0表示接收P1出错

    不使用nck简化了机制,来为后面实现流水线pipeline做准备

    综上所述的效果

    image-20230906114728476

  • 假设信道可能丢失分组,分组数据可能受损

    发送方采用超时重传机制,发送方发送分组后启动倒计数定时器,定时器过期后没有接收到ack,再次发送分组,其中ack丢失带来的发送重复分组,可以通过序号来处理

凡事都要做最坏的打算

流水线可靠数据传输协议

允许发送方在未得到对方确认的情况下一次发送多个分组需要的条件

  • 增加序号范围
  • 发送方缓存已发送未确定的多个分组:未得到确认,可能需要重传
  • 接收方缓存多个已接收的分组:上层用户取用数据的速率 ≠ 接收到的数据速率;接收到的数据可能乱序,排序交付(可靠)

两种通用的流水线协议:回退N步(Go-Back-N,GBN)和选择重传(Selective Repeat,SR)

滑动窗口

发送窗口:发送缓冲区内容的一个范围

接收窗口:控制哪些分组可以接收。 接收窗口 = 接收缓冲区

回退N步(Go-Back-N,GBN)

  • 发送窗口尺寸 > 1
  • 接收窗口尺寸 = 1

发送缓存

image-20230906195343476

发送方:

  • 发送窗口未满时,产生一个分组并将其发送,并把nextseqnum++;
  • 窗口已满,发送方只需将数据返回给上层,隐式地指示上层该窗口已满,或者先缓存下来以后发送
  • 只有最早的已发送但未被确认的分组拥有的定时器
  • 接收到ack后base++;如果此时base==nextseqnum则停止定时器,否则说明还有已发送但未被确认的分组,则重新开始计数器
  • 定时器超时则重新发送base~nextseqnum的所有分组

接收方:

  • 接收窗口的尺寸为1,只能顺序接收,接收后直接交付上方

    image-20230906214049306

    比如现在只有0可以接收,其他分组到达会被丢弃,接收后窗口滑动到1,向发送方发送ack,然后等待接收

选择重传(Selective Repeat,SR)

  • 发送窗口尺寸 > 1
  • 接收窗口尺寸 > 1

发送缓存

image-20230906225824770

发送方:

  • 发送窗口未满时,产生一个分组并将其发送,并把nextseqnum++;
  • 窗口已满,发送方只需将数据返回给上层,隐式地指示上层该窗口已满,或者先缓存下来以后发送
  • 所有已发送但未被确认的分组拥有的定时器
  • 只发送定时器超时的分组

接收方:

  • 接收窗口的尺寸 > 1,可以乱序接收
  • 低序号的分组到来,接收窗口移动
  • 高序号分组乱序到,缓存但不交付(因为要实现Reliable Data Transfer,不允许失序),不滑动,分组都收到后最后一起交付给上方

image-20230906214815621

  • 接收到分组后发送ACKn(ack+序号),由于这个ack可能丢失,所以不管接收方接收到什么分组,即使是当前窗口很早之前的分组,也应该发送ACKn,不然会导致发送方窗口不滑动

    对SR协议而言,这就意味着发送方和接收方的窗口 并不总是一致 。

窗口的最大尺寸

GBN: 2n-1

SR:2n-1

具体原因可以看

均是为了超时重传接受方能够区分到底是新数据还是老数据。

TCP

image-20230907131528781

序号:发送报文段数据首字节在应用层交下来字节流的偏移量+字节流初始序号(初始序号在建立连接时确定,一般随机地选择初始序号)

确认序号(Acknowledge number):期望从另一方收到的下一个字节的序号

首部长度:TCP选项字段是长度是可变的,导致报文段长度可变,4bit首部长度用来表示32bit的字为单位的TCP首部长度

表示字段

  • URG:紧急指针标志,为1时表示紧急指针有效,该报文应该优先传送
  • ACK:ACK = 1报文段为确认报文段,为0表示数据段不包含确认信息,确认号被忽略
  • PSH = 1 表示该报文段高优先级,接收方TCP应尽快推送给接收应用程序
  • RST = 1,表示 TCP 连接中出现严重错误,需要释放并重新建立连接,称为复位报文段
  • SYN = 1,表明这是一个请求连接报文段,称为同步报文段
  • FIN = 1,表示此报文段的发送方的数据已经发送完毕,并要求释放 TCP 连接,称为结束报文段

接收窗口:窗口大小的值是指,从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量。用于流量控制

以太网和PPP链路层协议都具有1500字节的MTU(Maximum Transmission Unit, MTU),去除20字节ip头,20字节TCP头,最大报文段长度(Maximum Segment Size,
MSS)一般为1460

可靠数据传输

TCP采用了类似于GBN的单一计时器,只为最早发送但未确认的报文段设置计时器,且定时器过期只发送这一个报文段

比如发送方发送了,数据流中0~1460的A报文段,1461~2921的B报文段,2922~4382的C报文段,后续报文段D,E,F,G,发送方只为0~1460的A报文段设置计时器

接收方接收到A报文,B报文段丢失,接收到C报文段,对于乱序的接收TCP程序员可自行处理,丢弃或者缓存,对于收到C D E F G都会向发送方发送确认序号为B的ACK,发送方接收到三个相同冗余的ACK则立即重传B分组,不用等计时器过期,这种操作叫快速重传

image-20230907215922072

TCP 3次握手

image-20230907220150943

  1. 客户端发送SYN=1,不包含应用层数据的tcp报文段,随机选择初始序号seq=J,称为同步报文段或SYN 报文段
  2. 服务器收到SYN报文段,服务器分配TCP缓存和变量,发送SYN=1,ACK=1,确认序号ack=J+1,随机选择初始序号seq=K的允许连接报文,称为SYNACK报文段
  3. 客户端收到 SYNACK 报文段后,客户端分配TCP缓存和变量,发送SYN=1 ACK=1,确认序号ack=K+1的报文确认连接,一般还会在此报文段携带数据

TCP 四次挥手

image-20230908002803834

  1. 客户端发送FIN=1,seq=u的结束报文段,FIN-WAIT-1 阶段,TCP半关闭阶段
  2. 服务器接收到客户端请求断开连接的 FIN 报文后,结束 ESTABLISHED 阶段,进入 CLOSE-WAIT 阶段并返回一段 TCP 报文,ACK=1,Seq = v,ack = u + 1,TCP半关闭阶段,而A收到B的确认后,进入FIN-WAIT-2状态,等待B发出的连接释放报文段
  3. 因为断开连接是A提出的,可能B还有数据要传输,所以不能和上一次ACK一起发,当B数据传输完毕后,B发出连接释放报文段
  4. A收到B的连接释放报文段后,对此发出确认报文段(ACK = 1,seq=u+1,ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSE状态。

为什么A在TIME-WAIT状态必须等待2MSL(最大报文生存时间)的时间?

  • 保证A、B正常进入CLOSED状态:最后一个ACK丢失可能丢失,TCP服务器进程对之前所发送的TCP连接释放报文段的超时重传,如果TCP客户进程属于关闭状态,会导致服务器反复重传无法关闭
  • 2MSL时长,可以使本次连接持续时间内所产生的所有报文段都从网络中消失,保证下一个新的TCP连接中,不会出现旧连接中的报文段

TCP拥塞控制

CongWin拥塞窗口 Threshold 慢启动动阙值

  • 当 CongWin < Threshold, 发送端处于慢启动阶段(slow-start ), 窗口指数性(平方增加MSS)增长
  • 当 CongWin > Threshold, 发送端处于拥塞避免阶段( congestion-avoidance ) , 窗口线性增长(+1 MSS)
  • 当收到三个重复的 ACKs(triple duplicate ACK),Threshold 设置成 CongWin/2 ,CongWin=Threshold+3.
  • 当超时事件发生时 timeout, Threshold=CongWin/2CongWin=1 MSS ,进入 慢启动SS 阶段