DJ3-4 传输层(第四节课)

目录

一、TCP 概述

二、TCP 报文段的首部字段格式

三、TCP 往返时延的估计和超时

1. 估计往返时间

2. RTT 估计例子

3. 估计往返时间的偏差

4. 设置重传超时间隔


一、TCP 概述

全双工服务:允许在同一时间同一连接上,数据能够双向传输。注意:TCP 可从缓存中取出并放入报文段中的数据数量受限于最大报文段长度(maximum segment size, MSS)

点到点:一个发送者,一个接收者;可靠按序的字节流。

面向连接:在数据交换前握手(交换控制信息),初始化发送方和接收方的状态。

没有 “信息边界”:假设我们需要发三个数据包,TCP 可能会因受限于 MSS 而把这三个包截断并组合后再发出。而 UDP 不会这样做,首先 UDP 会限制分组的大小从而使其适合发送,其次分组之间是相互独立的。因此,在 UDP 传输中不会出现把数据包截断的情况。

流量控制:使发送方不会淹没接收方。

TCP 拥塞和流量控制:

  • 设置窗口大小
  • 设置收发缓冲区

二、TCP 报文段的首部字段格式

TCP 报文段的构成:

  • 首部字段
  • 一个数据字段,包含了一块应用数据

MSS 限制了报文段数据字段的最大长度。


 

1. 源端口号和目的端口号

用于多路复用/分解来自或送到上层应用的数据。注意:发送时是多路复用,接收时是多路分解。

2. 序号和确认号

1)序号

序号 = 该报文段的第一个字节在字节流中的位置编号

一条 TCP 连接的双方均可随机地选择初始序号。

TCP 采用的是可靠按序的字节流:序号是建立在传送的字节流之上,而不是建立在传送的报文段的序列之上。换句话说,TCP 是以字节为单位来编号的,而不是以报文段为单位来编号。

2)确认号

主机 A 填充进报文段的确认号是主机 A 期望从主机 B 收到的下一字节的序号。换句话说,就是期望从主机 B 收到的下一报文段的序号。

由于每次都传输的是一个字节的数据,因此序号每次只加一。

3)累积确认

TCP 只确认字节流中至第一个丢失字节为止的字节。

主机 A 接收到来自主机 B 的包含字节 0~535 的报文段、字节 900~1000 的报文段,还没有接收到来自主机 B 的包含字节 536~899 的报文段。因此,主机 A 将在下一个发送给主机 B 的报文段中,把确认号字段设置为 536 。

3. 数据偏移/首部长度

该字段指示了以 32bit 为单位(即以 4 字节为单位)的 TCP 首部长度,即 TCP 报文段数据字段的起始处距离 TCP 报文段的起始处有多远。

4. 保留字段

占 6 位,保留为今后使用,但目前应置为 0。

5. 标志字段

3)紧急 URG(URGent)

当 URG=1 时,表明紧急指针字段有效。它告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)。紧急数据放在该报文段数据字段的最前面。

4)确认 ACK(ACKnowledgment)

只有当 ACK=1 时确认号字段的内容才有效;当 ACK=0 时,确认号字段的内容无效。

6)复位 RST(ReSeT)

当 RST=1 时,表明 TCP 连接中出现严重差错(如主机崩溃或其它原因),必须释放连接,然后再重新建立运输连接。

7)同步 SYN(SYNchronize)

当 SYN=1 时,表示这是一个连接请求或连接接受报文。

8)终止 FIN(FINish)

用来释放一个连接。FIN=1 表明此报文段的发送方的数据已发送完毕,并要求释放运输连接。

6. 窗口字段

该字段用于流量控制。占 16 位,是让对方设置发送窗口的依据,单位为字节。

7. 检验和

占16 位,在计算检验和时,要在 TCP 报文段前加上 12 字节的伪首部。

  • 伪首部
  • 首部字段
  • 数据字段

8. 紧急数据指针

占 16 位,指出在该报文段中紧急数据共有多少个字节,紧急数据放在该报文段数据字段的最前面。

9. 填充字段

该字段用于使整个首部长度是 4 字节的整数倍。

三、TCP 往返时延的估计和超时

Q:如何设置 TCP 的超时值?

A:显然需要比 RTT 长,但 RTT 是动态变化的,若时间

  • 太短:导致不成熟的超时和不必要的重传
  • 太长:导致对报文段丢失的响应慢

Q:需要设置几个定时器?

1. 估计往返时间

SampleRTT(样本RTT):测量从报文段发出到收到该报文段的确认信息的时间。

  • TCP 不会为重传的报文段计算 SampleRTT
  • TCP 仅在某个时刻为某报文段做 SampleRTT 测量,而非每一个

SampleRTT 是变化的,因此需要一个 SampleRTT 的均值,即 EstimatedRTT(均值RTT)

对收到的 SampleRTT 根据以下公式进行均值处理:

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

以编程的思想来理解该公式:即每次按公式来更新 EstimatedRTT 的值。

上述均值计算被称为 “指数加权移动平均”,RFC 推荐的 α 取值是 α=0.125 。

2. RTT 估计例子

由图可知,通过计算得到的 EstimatedRTT,我们能够保证有一半的报文段避免不成熟的超时。但是,我们还想要更多的紫线上方的报文段能够避免不成熟的超时,因此引入了 “安全余量”。

3. 估计往返时间的偏差

DevRTT(偏差RTT):用于估算 SampleRTT 一般会偏离 EstimatedRTT 的程度。

与前面类似,SampleRTT-EstimatedRTT 是变化的,因此需要一个 SampleRTT-EstimatedRTT 的均值,即 DevRTT(偏差RTT)

对收到的 SampleRTT-EstimatedRTT 根据以下公式进行均值处理: 

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

RFC 推荐的 β 取值是 α=0.25 。 

4. 设置重传超时间隔

根据前面的分析可知,超时间隔应该等于 EstimtedRTT 加上 “安全余量” DevRTT,从而避免不成熟的超时。同时。若 EstimatedRTT 波动较大,则需要加上更大的 “安全余量”。

最终超时间隔的公式为:

TimeoutInterval = EstimatedRTT + 4 * DevRTT

实际应用:

#init
TimeoutInterval = 1
EstimatedRTT = SampleRTT
DevRTT = SampleRTT/2

#update
TimeoutInterval = EstimatedRTT + max(G, 4*DevRTT)  #G是用户设置的时间粒度
DevRTT = (1 - β) * DevRTT + β * |SampleRTT - EstimatedRTT|
EstimatedRTT = (1 - α) * EstimatedRTT + α * SampleRTT

每次先更新 DevRTT 再更新 EstimatedRTT,否则 DevRTT 使用的就是不是上一次的 EstimatedRTT 了。

猜你喜欢

转载自blog.csdn.net/m0_64140451/article/details/130003403
今日推荐