计算机网络学习(七) 传输层 Ⅳ

正在学习计算机网络课程,以下是学习《计算机网络-自顶向下方法》的一些笔记,部分图片来自mooc网 哈尔滨工业大学 计算机网络课程:https://www.icourse163.org/course/HIT-154005

1. TCP:面向连接的传输协议

1.1 TCP概述

  • 面向连接的( connection- oriented) :这两个进程必须先相互"握手",即它们必须相互发送某些预备报文段,以建立确保数据传输的参数。
    • TCP 协议只在端系统中运行,而不在中间的网络元素(路由器和链路层交换机)中运行
    • 中间的网络元素不会维持 TCP 连接状态。 事实上,中间路由器对 TCP 连接完全视而不见,它们看到的是数据报,而不是连接。
  • 连接建立过程常被称为三次握手 ( three-way handshake)
  • 点对点:一个发送方,一个接收方
  • 全双工服务(full-duplex service) :同一连接能传输双向的数据流
  • 发起连接的进程被称为客户进程,而另一个进程被称为服务器进程。
  • TCP 连接的组成:两台主机上的缓存、连接状态变量、socket等
    在这里插入图片描述

1.2 TCP报文段结构

在这里插入图片描述

  • 源端口号(source port)和目的端口号(dest port):被用于多路复用/分解来自或送到上层应用的数据。
  • 同 UDP 一样, TCP 首部也包括检验和字段( checksum field)
  • 序号字段 (sequence number field)确认号字段( acknowledgment number field) :这些字段被 TCP 发送方和接收方用来实现可靠数据传输服务,讨论见后。
  • 接收窗口字段 (receive window field) :应用与流量控制,该字段用于指示接收方愿意接受的字节数量。
  • 4 bit 的首部长度字段 (header length field) : 有选项字段,所以 TCP 首部的长度是可变的。 (通常,选项字段为空,所以 TCP 首部的典型长度就是 20 字节 )
  • 选项字段 ( options field) :可选与变长的,用于双方协商最大报文段长度时,或在高速网络环境下用作窗口调节因子时使用。
  • 6 bit 的 标志字段 (flag field)
    • ACK 比特用于指示确认字段中的值是有效的;
    • RST、 SYN 和 FIN 比特用于连接建立和拆除;
    • 当 PSH 比特被设置的时候,就指示接收方应立即将数据交给上层(一般不用);
    • URG 比特用来指示报文段里存在着被发送端的上层实体置为"紧急"的数据(一般不用),紧急数据的最后一个字节由 16 比特的紧急数据指针字段指出 。
  • 序号与确认号:这两个字段是 TCP 可 靠传输服务的关键部
    • 1)序号:建立在传送的字节流之上,而不是建立在传送的报文段的序列之上。 因此一个报文段的序号是该报文段首字节的字节流编号
      • 例如:TCP 将某数据流构建成 500 个报文段,最大报文段长度为1000字节,则第一个报文段分配序号 0 ,第二个序号 1000 … ,每一个序号被填入到相应 TCP 报文段首部的序号字段中
      • 建立TCP连接时,双方随机选择序列号
    • 2)确认号:TCP 是全双工的,因此确认号是希望接收到的下一个字节的序号
      • 例1:主机 A 已收到了来自主机 B 的编号为 0-535 的所有宇节,同时假设它打算发送一个报文段给主机 B。 主机 A 等待主机 B 的数据流中字节 536 及之后的所有字节。 所以主机 A 就会在它发往主机 B 的报文段的确认号字段中填 上 536。
      • 例2:主机 A 己收到一个来自主机 B 的包含字节 0-535 的报文段,以 及另一个包含字节 900 -1000 的报文段。但主机 A 还没有收到字节 536 -899 的报文段。主机 A 为了重新构建主机 B 的数据流,仍在等待字节 536 (和其后的字节) 。因此,A 到 B 的下一个报文段将在确认号字段中包含 536。
      • 由例2看出,TCP 只确认该流中至第一个丢失字节为止的字节,所以 TCP 被称为提供累积确认( cumulative acknowledgment) 。
      • 在例2中,乱序到达的第三个报文段(字节 900 - 1000) 怎么处理呢?即TCP 连接中收到失序报文段时该怎么办?—— TCP 规范中没有规定,由 TCP 的编程人员做出决策(丢弃或暂时保存)

1.3 TCP可靠数据传输

1.3.1 概述

  • TCP 在 IP 层提供的不可靠服务基础上实现可靠数据传输,TCP 提供可靠数据传输的方法涉及我们在之前所学的许多原理。
  • 使用了流水线机制
  • 使用了累积确认
  • 使用了单一的重传计时器(与 SR 不一样,因为定时器的管理需要相当大的开销)
  • 触发重传的事件:超时、收到重复 ACK

1.3.2 合理的重传超时时间

  • 如何设置定时器的合理的超时时间?
    • 设置过短:不必要的重传
    • 设置过长:对段丢失的反应太慢
    • 但是一定要大于 RTT( round trip time),而 RTT 又是变化的
  • TCP 是如何测量估计 RTT ?
    • 报文段的样本 RTT( SampleRTT) :从某报文段被发出(即交给 IP) 到对该报文段的确认被收到之间的时间量
    • TCP 维持一个 SampleRTT 均值 (称为 EstimatedRTT) ,EstimatedRTT是一个 SampleRTT 值的加权平均值,α 参考值是 0.125
    • EstimatedRTT = (1 -α) · EstimatedRTT + α · SampleRTT
    • 即考虑了历史信息也考虑了最新的测量值,这种平均被称为指数加权移动平均 (Exponential Weighted Moving Average , EWMA)
  • 除了估算 RTT 外,测量 RTT 的变化也是有价值:
    • RTT 偏差 DevRTT,用于估算 SampleRTT 一般会偏离 EstimaLedRTT 的程度:
    • DevRTT = (1 -β) · DevRTT +β · | SampleRTT - EstimatedRTT |
    • 同样是指数加权移动平均
  • 最终得出定时器超时时间的设置:
    • EstimatedRTT 加上一定余量。 当 SampleRTT 值波动较大时,这个余量应该大些;当波动较小时,这个余量应该小些。 因此, DevRTT值应该在这里发挥作用了。
    • TimeoutInterval = EstimatedRTT + 4 · DevRTT

1.3.3 可靠数据传输的实现

  • TCP 发送方的三个事件
    • 从应用层收到数据
      • 将数据封装在一个报文段中并把该报文段交给 IP
      • 报文段包含一个序号,就是该报文段第一个数据字节的字节流编号
      • 如果定时器还没有为某些其他报文段而 运行,则当报文段被传给 E 时, TCP 就启动该定时器。
      • 该定时器的过期间隔是 TimeoutInterval
    • 超时
      • 重传引起超时的报文段
      • 重启定时器
    • 收到 ACK
      • TCP 将 ACK 的值 y 与它的变量 SendBase 进行比较
        • 状态变量 SendBase 是最早未被确认的字节的序号
        • SendBase -1 是指接收方已正确按序接收到的数据的最后一个字节的序号
        • TCP 采用累积确认,所以 y 确认了字节编号在 y 之前的所有字节都已经收到
      • 如果 y > SendBase,则该 ACK 是在确认一个或多个先前未被确认的报文段。
      • 更新 SendBase
      • 如果窗口中还有未被确认的分组,则重新启动定时器
    • 几个例子:
      • 例1:由于确认丢失而重传
        在这里插入图片描述
      • 例2:报文段100没有重传在这里插入图片描述
      • 例3:累积确认避免了第一个报文段的重传
        在这里插入图片描述

1.3.4超时间隔加倍

  • 这是大多数 TCP 实现中所做的一些修改
  • 当超时事件发生时, TCP 重传具有最小序号的还未被确认的报文段。只是每次 TCP 重传时都会将下一次的超时间隔设为先前值的两倍。因此,超时间隔在每次重传后会呈指数型增长
  • 然而,每当定时器在另两个事件(即收到上层应用的数据和收到 ACK)中的任意一 个启动时, Timeoutlnterval 由最近的 EstimatedRTT 值与 DevRTT 值推算得到
  • 这种修改提供了一个形式受限的拥塞控制。
    • 定时器超时很可能是由网络拥塞引起的
    • 在拥塞的时候,如果发送方持续重传分组,会使拥塞更加严重
    • 因此,TCP 使用更文雅的方式,每个发送方的重传都是经过越来越长的时间间隔后进行的。

1.3.5快速重传机制

  • 超时触发重传存在的问题之一是超时周期可能相对较长。 当一个报文段丢失时,这种较长的超时周期迫使发送方延迟重传丢失的分组,因而增加了端到端时延。
  • 先看一下 TCP 接收方的 ACK 生成策略:
    在这里插入图片描述
  • 发送方一个接一个地发送大量的报文段,如果一个报文段丢失,就很可能引起许多一个接一个的冗余 ACK
  • 如果 TCP 发送方接收到对相同数据的 3 个冗余 ACK,则假定在该报文段之后的报文段已经丢失,TCP 就执行快速重传(fast retransmit) :即在该报文段的定时器过期之前重传丢失的报文段

1.3.6 GBN or SR?

  • TCP 是一个 GBN 协议 还是一个 SR 协议?
  • 前面讲过, TCP 确认是累积式的,正确接收但失序的报文段是不会被接收方逐个确认的
  • 因此,TCP 发送方仅需维持已发送过但未被确认的字节的最小序号 ( SendBase) 和下一个要发送的字节的序号 ( NextSeqNum) 。 在这种意义下, TCP 看起来更像一个 GBN 风格的协议
  • 但是, 许多 TCP 实现会将正确接收但失序的报文段缓存起来。假设 n(n < N)的确认报文丢失,但是其余 N-1个确认报文在分别超时以前到达发送端,
    • GBN 不仅会重传分组 n, 还会重传所有后继的分组 n+1, n+2, … , N
    • TCP 则将重传至多一个报文段,即报文段 n
    • 此外,如果对报文段 n +1 的确认报文在报文段 n 超时之前到达, TCP 甚至不会重传报文段 n
  • 对 TCP 提出的一种修改意见是所谓的选择确认 ,它允许 TCP 接收方有选择地确认失序报文段,而不是累积地确认最后一个正确接收的有序报文段。此时,TCP 看起来就很像我们通常的 SR 协议。
  • 因此, TCP 的差错恢复机制也许最好被分类为 GBN 协议与 SR 协议的混合体

1.4 TCP的流量控制

  • 一条 TCP 连接的两个主机都为该连接设置了接收缓存RcvBuffer。该TCP连接接收到正确、按序的字节后,它就将数据放入接收缓存。
  • 应用进程会从该缓存中读取数据。 如果应用程序读取数据缓慢,而发送方发送得太多太快,发送的数据就会很容易地使该连接的接收缓存溢出。
  • 流量控制服务( flow-control service) : TCP 为它的应用程序提供了流量控制服务,以消除发送方使接收方缓存溢出的可能性。本节假设 TCP 接收方丢弃失序的报文段。
    • 速度匹配服务:即发送方的发送速率与接收方应用程序的读取速率相匹配
    • 接收方有RcvBuffer:
      在这里插入图片描述
    • 其中接收窗口 RcvWindow 用于提示发送方该接收方还有多少可用的缓存空间,RcvWindow = RcvBuffer - [LastByteRcvd - LastByteRead ]
    • 接收方通过在报文段的头部字段将 RcvWindow 告诉发送方,发送方限制自己已经发生的但还未收到 ACK 的数据不超过接收方的空闲 RcvWindow 的尺寸,具体:
      • 发送方 轮流跟踪两个变量, LastByteSent 和LastByteAcked
      • 这两个变量之间的差LastByteSent - LastByteAcked ,就是发送方发送到连接中但未被确认的数据量
      • 将该数据量控制在值 RcvWindow 以内,就可以保证不会使接收缓存溢出
  • 一个小问题:假设接收缓存已经存满,使得发送方收到 RcvWindow =0,则发送方将停止发送数据。而当接收方的接收缓存已经有新的空间时,发送方又不可能知道。即主机 A 被阻塞而不能再发送数据!
    • 解决: TCP 规范中要求接收方的接收窗口为 0 时,发送方继续发送只有一个字节数据的报文段。 这些报文段将会被接收方确认。 最终缓存将开始清空,并且确认报文里将包含一个非 0 的 RcvWindow 值
  • UDP 并不提供流量控制

1.5 TCP连接管理

如何建立和拆除一条 TCP 连接?

  • TCP 连接的建立过程:3 次握手 ( three- way handshake)
    • 第一步:客户端的 TCP 向服务器端的 TCP 发送SYN 报文段
      • 不包含应用层数据,但在报文段的首部中的一个标志位 (即 SYN 比特)被置为 1
      • 客户会随机地选择一个初始序号( client_isn) ,此编号放置于该起始的 TCP SYN 报文段的序号字段中。
    • 第二步:服务器端收到 SYN 报文段,回复允许连接的报文段SYNACK 报文段
      • 服务器为该 TCP 连接分配 TCP 缓存和变量
      • 这个允许连接的报文段也不包含应用层数据,但是 SYN 比特被置为 1 ;并且 TCP 报文段首部的确认号字段被置为 client_ isn + 1 ;,服务器选择自己的初始序号 (server_isn) ,其放置到 TCP 报文段首部的序号字段中
      • SYNACK 的含义:我收到了你发起建立连接的 SYN 分组,该分组带有初始序号 client_isn。 我同意建立该连接。 我自己的初始序号是 server_isn
    • 第三步:客户端收到 SYNACK ,对此向服务器发送一个 ACK,表明自己收到了服务器的允许连接的报文段
      • 客户通过将值 server_isn + 1 放置到回复报文段首部的确认字段中来完成此项工作
      • 可以在该报文段携带客户到服务器的数据
      • SYN 比特被置为 0
      • 客户也要给该连接分配缓存和变量
  • 完成这 3 个步骤,客户和服务器主机就可以相互发送包括数据的报文段了。 在以后每一个报文段中, SYN 比特都将被置为 0。
    在这里插入图片描述
  • TCP 连接的关闭:
    • 第一步:客户 TCP 向服务器进程发送一个特殊的 TCP 报文段(首部的一个标志位 FIN 比特被设置为 1
    • 第二步:当服务器接收到 FIN 后,向发送方回送一个 ACK。 然后,服务器关闭连接,发送自己的 FIN
    • 第三步:服务器收到 FIN,回复 ACK,并进行定时等待:如果收到 FIN,则重新发送 ACK
    • 第四步:服务器收到 ACK,连接关闭
      在这里插入图片描述

2.拥塞控制原理

  • 非正式定义:太多主机发送了太多数据或者发送的速度太快,以至于网络无法处理
  • 表现:
    • 分组丢失(路由器缓存溢出)
    • 分组延迟过大(在路由器缓存中排队)
  • 之后将详细研究 TCP 用于拥塞控制的特定方法。 这里,我们指出在实践中所采用的两种主要拥塞控制方法:
    • 端到端拥塞控制
      • 网络层没有为运输层拥塞控制提供显式支持
      • 端系统必须通过对网络行为的观察(如分组 丢失与时延)来推断
      • TCP采用这种方法
    • 网络辅助的拥塞控制
      • 网络层构件(路由器)向发送方提供关于网络中拥塞状态的显式反馈信息
      • 这种反馈可以简单地用一个比特来指示链路中的拥塞情况
      • 拥塞信息从网络反馈到发送方通常有两种方式
        • 路由器把反馈信息直接发给发送方
        • 路由器在分组中标记拥塞产生,再由接收方向发送方通知该网络拥塞

3.TCP拥塞控制原理

  • TCP 必须使用端到端拥塞控制而不是使网络辅助的拥塞控制,因为 IP 层不向端系统提供显式的网络拥塞反馈
  • TCP 所采用的方法是让每一个发送方根据所感知到的网络拥塞程度来限制其能向连接发送流量的速率,主要有以下三个问题:
    • 第一,一个 TCP 发送方如何限制它向其连接发送流量的速率?
    • 第二,一个 TCP 发送方如何感知从它到目的地之间的路径上存在拥塞?
    • 第三,当发送方感知到端到端的拥塞时,如何合理地改变其发送速率?
  • 第一个问题:
    • 运行在发送方的 TCP 拥塞控制机制跟踪一个额外的变量,即拥塞窗口 (congestion window,cwnd)
    • 它对一个 TCP 发送方能向网络中发送流量的速率进行了限制
    • 发送方的发送速率大概是 cwnd / RTT 字节/秒
    • 通过调节 cwnd 的值,发送方因此能调整它向连接发送数据的这率
  • 第二个问题:
    • 发生丢包事件(超时或收到 3 个冗余 ACK) ,发送方就认为在路径上出现了拥塞的指示
  • 第三个问题:
    • 加性增 - 乘性减:AIMD
    • 慢启动:Slow Start(SS)
  • AIMD
    • 逐渐增加发送速率,谨慎探测可用带宽,直到发生 loss
    • Additive Increase:每个 RTT 将 cwnd 增大一个MSS —— 拥塞避免的思想
    • Multiplicative Decrease:发生 loss 后将 cwnd 减半
  • 慢启动:
    • 在慢启动状态, cwnd 的值以 1 个 MSS 开始并且每当传输的报文段首次被确认就增加 1 个 MSS。 因此, TCP 发送速率起始慢,但在慢启动阶段以指数增长
      在这里插入图片描述
    • 何时结束这种指数增长?
      • 1.如果存在一个由超时指示的丢包事件(即拥塞),则将 cwnd 设置为 1 并重新开始慢启动过程。还将第二个状态变量的值 ssthresh ( "慢启动阔值"的速记) 设置为 cwnd / 2
      • 2.当 cwnd 的值等于或超过 ssthresh 时, 结束慢启动并且 TCP 转移到拥塞避免模式更为谨慎地增加 cwnd,即进入线性增长阶段
      • 3.如果检测到 3 个冗余 ACK ,则 cwnd 的值减为一半,然后线性增长
    • 拥塞避免
      • 上文提到,一旦进入该状态, cwnd 的值大约是上次遇到拥塞时的值的一半, 距离拥塞并不遥远!
      • 因此采用了一种保守的方法:每个 RTT 只将 cwnd 的值增加一个 MSS (线性增长)
    • 总结:
      • 当 cwnd < ssthresh 时,慢启动阶段,指数增长
      • 当 cwnd >= ssthresh 时,拥塞避免阶段,线性增长
      • 当收到 3 个重复 ACK 时, cwnd 的值和 ssthresh 的值都减为一半
      • 当超时发生时,cwnd 直接设为 1,ssthresh 减为一半
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值