TCP报文段、序号和确认号的确定、往返时间和超时时间的估计、超时时间加倍、快速重传、GBN\SR

TCP 建立连接的前两个报文段不包含应用层数据,第三个报文段可以承载有效数据。

建立连接以后,TCP将数据引导到该连接到发送缓存里,发送缓存是发起三次握手期间设置的缓存之一。

MSS:最大报文段长度,报文段里应用数据的最大长度。(1460-1480) 而不是包含首部的TCP报文段最大长度。

MTU:最大链路层帧长度,及最大传输单元,一般为1500字节。

TCP 报文段结构

TCP报文段由首部字段和一个数据字段组成。 MSS限制了报文段数据字段的最大长度。

TCP的首部一般是20B,Telnet发送的报文段长度也许是21B。

  • 2B的 源端口号 2B的 目的端口号 :用于多路复用/分解

  • 4B的序号 4B的确认号: 用于实现可靠数据传输

  • 2B的接收窗口:用于流量控制,指示接收方愿意接受的字节数量

  • 2B的检验和: 检验数据传输是否出现bit改变

  • 2B的紧急数据指针: TCP必须通知接收端的上层实体

  • 4bit的 首部长度: TCP报文段的首部长度,一般为20B

  • 6bit的 标志字段

    1. ACK : 指示确认字段中的值是有效的
    2. RST、SYN、FIN:连接建立和拆除
    3. CWR、ECE: 明确拥塞通告

这两个在实践的时候并没有被使用,为了完整,记录在下。

1. PSH:指示接收方需要立刻将数据交给上层
2. URG:指示报文段里存在着被发送段的上层实体置为“紧急”的数据

image

1. 序号和确认号

  1. TCP首部的序号和确认号是可靠传输服务的关键部分
  2. TCP把数据看成无结构、有序的字节流
  3. 序号建立在传送的字节流上,而不是建立在传送的报文段的序列之上
  4. 报文段的序号字段是该报文段数据字段首字节的序号
  5. 确认号是该主机 正在在等待的数据的下一字节的序号
  6. 客户到服务器的数据的确认 被装载在 服务器到客户到数据的 报文段中: 这中确认被称为 捎带在服务器到客户到数据报文中的。

TCP会对数据流中的每一个字节编号,假设数据流为500_000字节的文件组成,其中MSS=1000B,数据流的首字节编号为0。那么TCP为这个数据流构建500个报文段。给一个报文段分配序号0,第二个报文段分配序号1000,第三个报文段分配序号2000。
每一个序号被填入到相应TCP报文段首部的序号字段中。
因为是全双工通信,主机A填充进报文段的确认号是 主机A期望从主机B收到的下一字节的序号。
假设主机A已经收到来自主机B的编号为0-535的所有字节,主机A就会在它发往主机B的报文段的确认号字段中填上536。
当主机在一条TCP连接中收到失序报文段时该怎么办?
TCP的RFC并没有为此明确任何规则,把这一问题留给实现TCP编程人员去处理 。
有两个基本的选择:

  1. 接收方立即丢弃失序报文段
  2. 接收方保留失序的字节,并等待缺少的字节以填补该间隔。该种方式是实践中采用的方式。
    初始序号可以随机选择,减少仍在网络中存在的报文(主机已经终止连接了),被误认为有效报文的可能性。

2. 往返时间的估计与超时

2.1 估计往返时间

超时间隔必须大于连接的往返时间RTT

  1. TCP绝不为已被重传的报文计算SampleRTT
  2. TCP仅为传输一次的报文段测量SampleRTT
  3. SampleRTT : 从某报文段被发出(交IP)到对该报文的确认被收到之间的时间量。 (仅在某个时刻做一次这个测量)
  4. 指数加权移动平均, TCP会维护一个EstimatedRTT = (1 - alpha) * EsimatedRTT + alpha * SampleRTT, RFC 6298中 alpha = 0.125
  5. RTT偏差,DevRTT = (1 - beta) * DevRTT + beta * |SampleRTT - EstimatedRTT|, beta = 0.25, 波动很大的时候,DevRTT的值会很大。

2.2 设置超时时间

超时时间 TimeoutInterval = EstimatedRTT + 4 * DevRTT
推荐的初始TimeoutInterval = 1s。
出现超时后,TimeoutInterval的值会加倍。避免以及被确认的后继报文段过早出现超时。
只要收到报文段后,就会更新新的EstimatedRTT。

隐式NAK机制: 连续收到对一个特定的报文段的3个冗余ACK可以作为对后面报文段的一个隐式NAK。
TCP使用的是

3.TCP可靠数据传输

TCP可靠数据传输服务确保: 一个进程从其接受缓存中读出的数据是无损坏、无间隙、非冗余和按序到达的数据流。
TCP协议遵循了单一定时器的推荐: 定时器管理过程仅使用单一的重传定时器,即有多个已发送但还未被确认的报文段。

TCP发送方有3个与发送和重传有关的主要事件: 从上层接受数据、定时器超时和收到ACK。

  1. 从上层接受数据: TCP从应用接受数据,将数据封装到一个报文段中,并把该报文段交给IP层。每一个报文段都包含一个序号,这个序号是第一个数据字节的字节流编号。 如果此时定时器没有启动,就启动该定时器,过期时间间隔=TimeoutInterval。
生存TCP报文段
if 定时器没有启动: 启动定时器
向IP传递报文段
nextseqnum = nextseqnum + length(data)
  1. 定时器超时
重传具有最小序号但仍未应答的报文段
启动定时器
  1. 接收ACK
    因为TCP采用了累计确认,如果y > sendBase,那么ACK是在确认一个或者多个先前未被确认的报文段。
if (y > sendBase):
	sendBase = y
	if 仍无任何应答报文段: 启动定时器

介绍几种例子:

  1. A->B: seq = 92, data = 8B
    B ->A: ack = 100, 丢失了,
    超时
    A->B: seq = 92, data = 99
    B->A: ack = 100,接收到, 数据会丢失
    image

  2. A-B: seq = 92, data = 8B
    A-B:seq = 100, data = 20B
    B-A:ack = 100
    B-A: ack = 120
    A-B的第一段数据报超时,然后重传第一段,定时器重启
    B-A:ack = 100 和120到达,如果120在新的定时器超时之前到达,那么第二个报文不会被重传。
    如果ack=120到达的时候,第一个定时器没有超时,那么第一个报文也不会进行重传。
    image
    image

超时间隔加倍

当出现超时事件发生的时候,会将超时间隔设为之前的两倍,而不是使用estimatedRTT和devRTT估算的值。
但是当另外两个事件发生的时候,timeoutinterval 又由estimatedRTT和devRTT估算得到。

  1. 收到ACK
  2. 收到上层数据

快速重传

超时触发重传存在的问题: 迫使发送方延迟重传丢失的分组,造成了端到端的时延。
TCP接收方接收到一个数据报,其序号大于rcv_base,那么它将对最后一个按序字节数据进行重复确认(这样就产生了一个冗余ACK)。
一旦收到3个冗余ACK,那么TCP就会执行 快速重传,即在该报文段定时器过期之前重传丢失的报文段。

GBN/SR?

  1. TCP确认是累计的,正确接收但是失序的报文时不会被接收方逐个确认的。
  2. TCP发送方仅需维护sendBase以及nextseqnum。

看起来和GBN风格的协议很像,但是:

  1. TCP实现会将正确接收但失序的报文段缓存起来。
  2. 如果n丢失,GBN会重传n、n+1、... N,但是TCP只会重传报文段n。
  3. 如果对报文段n+1的确认段报文在报文段n超时之前到达,TCP不会重传这个报文段n。

RFC2018:允许TCP接收方有选择的确认失序报文段,而不是累计确认最后一个正确接收的报文段。

posted @   CrazyShanShan  阅读(2459)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示