传输层服务介绍(下)

Scroll Down

传输层服务介绍(下)

TCP协议介绍

TCP的特点:

  • 点对点,只能是一个接收方和一个发送方
  • 可靠的按序的字节流
  • 流水线机制,TCP拥塞控制和流量控制机制,动态的设置窗口尺寸
  • 发送方/接收方会有缓存
  • 是全双工连接(同一连接能够传输双向数据量)
  • 面向连接,通信双方在发送数据之前必须建立连接,连接状态只在连接的两端中维护,在沿途节点中并不维护状态
  • 流量控制机制和拥塞控制机制

TCP段结构

image-20200204151424267

序列号:

  • 序列号指的是segment中的第一个字节的编号,而不是segment的编号,比如有1KB的数据,将其拆成两个segment,第二个segment的序列号是500 or 501
  • 建立TCP连接时,双方随机选择序列号

ACKs:

  • 希望接收到的下一个字节的序列号
  • 累计确认:该序列号之前的所有字节均已正确接收到(类似GBN的累计确认机制)

TCP协议中乱序到达的Segment由TCP的实现着做决策

TCP的可靠数据传输

  • TCP在IP层提供的不可靠服务基础上实现可靠数据传输服务
  • 流水线机制提高性能
  • 累积确认,类似GBN协议
  • TCP使用单一重传计时器
  • 触发重传的事件(超时,或者收到重复的ACK)

如何设置定时器的超时时间?

首先要设计一个合理的超时时间,要大于RTT,但是RTT是动态变化的,不能过短,否则会导致不必要的重传,不能过长,会对段丢失时间反应慢

如何估计RTT?

SampleRTT:测量从段发出到收到ACK的时间

测量多个RTT,求平均值,形成RTT的估计值得到EstimatedRTT

EstimatedRTT = (1-α) * EstimatedRTT +α * SampleRTT

其中α = 0.125

定时器的超时时间设置

EstimatedRTT +一个安全边界,如果EstimatedRTT 变化较大,则需要一个较大的边界

测量RTT的变化值:SampleRTT与EstimatedRTT 的差值

DevRTT = (1-β)DevRtt + β |SampleRTT - EstimatedRTT |

其中β = 0.25

最终超时时间 = EstimatedRTT + 4* DevRTT

TCP发送方事件

从应用层收到数据:

  1. 创建Segment
  2. 序列号是Segment第一个字节的编号
  3. 开启计时器
  4. 设置超时时间

如果此时超时:

  1. 重传引起超时的Segment
  2. 重启定时器

收到ACK时

如果确认此前未确认的Segment

  • 更新SendBase
  • 如果窗口中还有未被确认的分组,重新启动计时器

TCP重传示例

image-20200204153241464

1.首先HostA传送序列号为92,8字节的数据给HostB,此时HostB返回ACK=100,此时丢失了超时了,HostA重新传递Seq = 92,8字节的数据,此时HostB继续返回ACK = 100,然后结束

2.首先发送Seq=92,8个字节的额数据,seq=100,20个字节的数据,然后返回ACK=100的请求超时了,此时HostA重新发送Seq=92,8个字节的数据,此时HostB因为已经收到了ACK=120的数据,此时返回ACK = 120(累计确认),HostA将sendBase更新为120

TCP的ACK生成:RFC 1122,RFC 2581

image-20200204153659686

接收方事件接收方的动作
当收到期望的按序的报文段时,并且之前的报文都已经回复了ACK了延迟返回ACK,等待500ms,看是否有下一个报文段前来,如果没有,则返回ACK
当收到期望的报文段时,并且接收方已缓存了上一个报文段没有返回ACK的此时直接发送缓存的报文段与本报文段的ACK(累计确认)
如果接收到乱序的报文段,此时检测出中间有空(gap)需要发送重复的ACK,告知发送方需要收到的ACK
如果收到了报文段填充上了之前乱序的报文段发送此时相连的最后的报文段的ACK

快速重传机制

  • TCP的实现中,如果发生超时,超时时间间隔将重新设置,将超时时间间隔加倍,导致时间很大,重发丢失分组需要等待很长的时间
  • 通过重复ACK检测分组丢失,因为采用流水线机制,如果某个分组丢失,接收方会返回多个重复的ACK,如果sender收到对同一个数据的3个ACK,则假定该数据后面的段都已经丢失,此时使用快速重传:在定时器超时之前就开始重传

为什么是收到3次重复的ACK之后就可以判断为丢失并开始快速重传?

20190715222926241

如上图所示,ACK=3的时候,乱序的大部分情况下会收到2个相同的ACK,只有40%的情况下是因为乱序而非丢失所导致的,如果丢失的话一定会收到3个及以上的ACK,所以综合考虑3次为较好的选择

TCP的流量控制

接收方为TCP连接分配buffer
image-20200204155104232

收到发送方传来的数据,逐步交给上层(应用层)处理数据,如果上层应用速度较慢,发送方就会发送的太多,导致接收方的buffer溢出

流量控制是一种速度匹配机制

Sender方限制自己已经发送的但还未收到ACK的数据不超过接收方的空闲RcvWindow的尺寸

Receiver告诉Sender的RcvWindow=0,会出现什么情况?

此时需要增加一个额外的处理,及时是rcvWindow=0的时候,sender方也可以发送一个较小的报文段给receiver方,带回最新的rcvwindow值,防止死锁的产生

TCP连接管理

TCP需要进行连接的建立,连接的拆除

TCP sender和receiver在传输数据前需要建立连接,比如分配缓存,交换流量控制信息

TCP的连接是采用了三次握手机制

TCP连接的建立

TCP的连接分三个阶段:

image-20200204155823491

  1. 发送方发送一个SYN报文段给服务方,此时是不携带数据的,需要建立一个初始的随机的序列号
  2. 此时接收方如果可以建立连接,此时会回应一个SYNACK报文段,接收方会为这个连接分配缓存,选择接收方初始的序列号并告知客户端
  3. 发送方收到了SYNACK报文段之后,会答复一个ACK报文段,此时SYN标志位不再为1,是告诉接收方_发送方已经收到了接收方同意建议连接的报文段,并且可以携带数据传递

image-20200204160325257

为什么要采用三次握手机制?

三次握手主要是为了统一发送方和接收方的初始序列号,TCP 的可靠连接是靠 seq( sequence numbers 序列号)来达成的,TCP 协议是不限制一个特定的连接(两端 socket 一样)被重复使用的。
TCP 需要 seq 序列号来做可靠重传或接收,而避免连接复用时无法分辨出 seq 是延迟或者是旧链接的 seq,因此需要三次握手来约定确定双方的 ISN(初始 seq 序列号)。
所以这样就有一个问题:这条连接突然断开重连后,TCP 怎么样识别之前旧链接重发的包?
——这就需要独一无二的 ISN(初始序列号)机制。当一个新连接建立时,初始序列号( initial sequence number ISN)生成器会生成一个新的32位的 ISN。这句话的意思是:一个 seq 过来了,跟现在记住的 seq 不一样,我怎么知道他是上条延迟的,还是上上条延迟的呢?

所以,接收方一定需要跟发送方确认 SYN。

TCP 为什么是三次握手,而不是两次或四次? - HioHio的回答 - 知乎 https://www.zhihu.com/question/24853633/answer/573627478

假如发送方收到了SYNACK的报文段,但是不发送ACK给接收方,会导致什么后果?

如果此时ACK在网络中丢失,那么Server端该TCP连接的状态为SYN_RECV,并且依次等待3秒、6秒、12秒后重新发送SYN+ACK包,以便Client重新发送ACK包,以便Client重新发送ACK包。
如果重发指定次数后,仍然未收到ACK应答,那么一段时间后,Server自动关闭这个连接。

如果故意不发送ACK的话,则是 Syn洪水攻击 ,收到SYN ACK 还未发送ACK时称为半开放连接,因为服务器在回复SYN ACK的时候就已经为TCP连接分配了资源,会导致服务器的资源消耗过大,导致正常用户的请求无法得到响应.

TCP连接的关闭

  1. 发送方向接收方发送TCP FIN控制segment段
  2. 接收方收到FIN,恢复ACK,关闭连接,并发送FIN报文段
  3. 发送方收到FIN,回复接收方ACK,进入等待状态,如果等待状态时,重复收到FIN,此时需要重新发送ACK给接收方
  4. 服务端收到ACK,连接关闭

image-20200204160833523

TCP的生命周期

发送方的生命周期

image-20200204160922019

假如一个应用端需要发起一个TCP连接,首先发送一个SYN报文段,进入SYN_SENT状态,收到SYNACK标识后,发送ACK给接收方,此时进入ESTABLISHED进入连接已建立状态,此时已经可以为上层应用进行数据传输.

如果客户端需要关闭该TCP连接,此时客户端发送FIN给接收方,此时进入FIN_WAIT_1状态,收到接收方的ACK状态,发送方进入FIN_WAIT_2状态,接收方会发出FIN给发送方,发送方收到FIN后回复ACK后,进入TIME_WAIT状态,此时等待30秒后,连接关闭

接收方的生命周期

image-20200204161642727

服务器一直处理Listen状态,此时接收到发送方传递的SYN标志,接收方回复SYN ACK,进入SYN_RCVD状态,然后再接收发送方的ACK后连接建立,进入ESTABLISHED状态,此时可以为应用层传输数据了.

当接收到FIN标识时,证明是客户端发起了关闭TCP连接的请求,此时返回ACK并进入CLOSE_WAIT状态,并发送FIN 给发送方,发送方返回ACK后,接收方关闭连接.

拥塞控制原理

拥塞(Congestion)

非正式定义:"太多主机发送了太多数据或者发送速度太快,以至于网络无法处理"

表现为:分组丢失(路由器缓存溢出),分组延迟过大(在路由器缓存中排队)

拥塞控制 (不要让网络处理不了)VS 流量控制(不要让接收方处理不了)

拥塞的代价

性能吞吐率下降,因为分组丢失和重传回导致效率的下降

当有多个路由器并且有多个网络进行拥塞时,下游的传输失败会导致该分组上游已传输成功的能力都浪费掉

发送数据和接收数据线形图

一旦速度大到一定程度,会导致整个网络直接瘫痪,无法使用

image-20200204211324433

拥塞控制的方法

端到端拥塞控制:

  • 网络层不需要显式的提供支持
  • 端系统通过观察loss,delay等网络行为判断是否发生拥塞
  • TCP采取方法

网络辅助的拥塞控制:

  • 路由器向发送显式的反馈网络拥塞信息
  • 简单的拥塞提示(1bit):SNA,DECbit,TCP/IP ECN,ATM
  • 提示发送方应该采取何种速率

ATM ABR拥塞控制

ABR:available bit rate

  • 弹性服务
  • 如果发送方路径比较宽,则尽可能使用可用带宽
  • 如果发送方路径拥塞,将发送速率降到最低报账速率

RM(Resource Managment) cells

  • 发送方发送
  • 交换机设置RM cell位(网络辅助),设置NI bit:rate 不去增长,设置的是CI bit:拥塞指示
  • RM cell由接收方返回给发送方,网络路径中的任一路由器都有可能改变RM cell位,则可知道路径是否拥塞或者最大速率是多少
    image-20200204212206722

每隔若干个分组,则发送RM cells分组,RM cell中有显式的速率字段,拥塞的交换机可以将ER置为更低的值,发送方获知路径中实时所能支持的最小速率

数据cell的EFCI位:拥塞的交换机将其设为1,如果RM cell前面的data cell的EFCI位被设为1,那么发送方在返回的RM cell中置为CI位

TCP拥塞控制的基本原理

Sender限制发送速率:设置一个CongWin(拥塞的窗口值),LastByteSent-LastByteAcked <= CongWin

速率rate ≈CongWin/Rtt

Cong Win:

  • 动态调整以改变发送速率
  • 反映所感知到的网络拥塞

如何感知网络拥塞?

Loss事件=timeout或3个重复的ACK,发送Loss事件后,发送方就降低速率

如何合理的调整发送速率?

加性增-乘性减:AIMD

  • 拥塞避免,原理为:逐渐增加发送速率,谨慎探测可用带宽,知道发生loss事件

  • Additive Increase:线性增加,每个RTT将CongWin增大一个MSS(最大段的长度)-拥塞避免

  • Multiplicative Decrease:发生loss事件后,将CongWin减半(将速率减半)

image-20200204213131905

像一种锯齿一样的行为,逐渐试探并减半

慢启动:SS

  • 当TCP连接建立时,将CongWin = 1初始化,
  • 可用带宽可能远远高于初始速率.刚增长的时候,如果线性增加时间消耗过久,希望能够快速增长,所以当连接开始时,让CongWin大小呈指数性增长.
  • 每个RTT将CongWin翻倍
  • 收到每个ACK就进行操作
  • 初始速率很慢,但是快速攀升

何时应该指数性增长切换为线性增长(拥塞避免)?

当CongWin达到Loss事件前值的1/2时

实现方法:

声明一个变量Threshold

Loss事件发生时,Threshold被设为Loss事件前CongWin值的1/2

image-20200204213827406#### Loss事件的处理

当收到3个重复ACKs:

  • CongWin切到一半
  • 然后线性增长

当Timeout事件发生时:

  • CongWin直接设为1个MSS
  • 然后指数增长
  • 达到threshold后,再线性增长

为什么重复的ACKs和timeout事件的处理方式不一样?

3个重复的ACKS表示还能够传输一些Segement,timeout事件表名拥塞更为严重,则需要将CongWin设为1个MSS

TCP拥塞控制总结

image-20200204214256954

  1. 当CongWin大小低于Threshold时,发送方处于慢启动阶段,此时处于指数增长
  2. 当CongWin大于Threshold时,发送方处于拥塞避免阶段,需要呈指数性增长
  3. 当收到3个ACK的时候,将CongWin置为一半
  4. 当timeout发生时,将CongWin置为1个MSS

例题
image-20200204214920779

TCP的性能分析

TCP throghput:吞吐率

给定拥塞窗口大小和RTT,TCP的平均吞吐率是多少?(忽略掉Slow start)

假定发生超时时CongWin的大小为W,吞吐率是W/RTT

超时后,ConWin = W/2,吞吐率是W/2RTT

所以平均吞吐率为 0.75W/RTT

TCP的公平性

如果K个TCP Session共享相同的瓶颈带宽R,那么每个Session的平均速率为R/K

TCP和UDP之间共存该如何处理?

  • 多媒体应用通常不适用TCP,以免被拥塞控制机制限制速率
  • 使用UDP:以恒定速率发送,能够容忍丢失
  • 产生了不公平

公平性与并发TCP连接

某些应用会打开多个并发连接,导致应用抢占过多的速率,假设链路速率为R,已有9个连接,新来一个应用请求1个TCP,获得了R/10的速率,新来的应用B开启11个连接,则获得了R/2的速率

传输层总结

传输层服务的基本原理

  • 多路复用/分用
  • 可靠数据传输
  • 流量控制
  • 拥塞控制

Internet的传输层

  • UDP
  • TCP