面向连接的传输: TCP
TCP:概述
- 提供的是点对点的服务: 一个发送方,一个接收方
- 可靠的、按顺序的字节流 : 没有报文边界
- 管道化(流水线): TCP拥塞控制和流量控制设置 窗口大小
- 发送和接收:
- 全双工数据 : 在同一连接中数据流双向流动 ,两者可以互相发 ( ==MSS:最大报文段大小 [任意一个网络都有它最大的传输部分,如果应用交互的报文非常长的话,就必须打成一个个MSS的大小。每层都要加上头部信息==])
- 面向连接: 在数据交换之前,通过握手(交换控制报文) 初始化发送方、接收方的状态 变量
- 有流量控制: 发送方不会淹没接收方
段结构
TCP报文段结构
源端口号:16bit
目标端口号: 16bit
序号: 32bit
TCP序号,确认号:
序号:
- 报文段首字节 的在字节流的编号
如果初始序号为X, 那么第n个序号就是X + n*MSS
序号具体就是: 上层交互的报文 ,我们按照MSS为单位,切割成为一个个的MSS报文段。 每个TCP都有头部和Body部分, Body部分就是MSS的载荷部分。载荷部分(Body)中的第一个字节就是MSS在整个报文中的偏移量.
确认号:
- 期望从另一方收到的下一个字节的序号
- 累积确认
发送方发送, 接收方接收, 假设接收方发送了ACK为555, 那么就说明接收方接收到了554及其之前的所有字节。而且期望发送方从556的序号开始发送
首部长度:
- 4bit
保留未用:不太清楚
标志位: UAPRSF
接收窗口 : 用于流量控制。 (如果接收窗口为 X, 那么就表示能接收 Xbit的数据)
紧急指针: 不怎么用。
TCP面临的通信场景(往返延时(RTT)和超时 )
采用自适应的策略和计算。
1.怎样设置TCP 超时?
如果比RTT要长 , 但RTT是变化的
如果太短:太早超时 会产生不必要的重传
如果太长:对报文段丢失 反应太慢,消极
2.怎样估计RTT?
SampleRTT:测量从报文段发出到 收到确认的时间
如果有重传,忽略此次测量
SampleRTT会变化,因此估计的 RTT应该比较平滑
对几个最近的测量值求平均,而 不是仅用当前的SampleRTT
3.EStimatedRTT(估计的往返延迟时间)的计算:
EstimatedRTT = (1- a)*EstimatedRTT + a*SampleRTT
- 指数加权移动平均
- 过去样本的影响呈指数衰减
- 推荐值:a = 0.125
往返延迟时间分布:
设置超时
平均值越大, 我们设置的超时时间就需要变大
往返延迟的变化越大, 就会越分散 , 超时时间就需要设置的越大。
EstimtedRTT + 安全边界时间
- EstimatedRTT变化大 (方差大 ) -> 较大的安全边界时间
SampleRTT会偏离EstimatedRTT多远:
当前的采样值, 离偏差程度的一个平均值。
可靠数据传输(TCP怎么实现RDT)
我们知道IP提供的是不可靠的服务 ,而TCP向上层提供的确是可靠的服务, 那么这是如何实现的呢 ?
TCP在IP不可靠服务的基础上 建立了rdt
- 管道化的报文段 • GBN or SR (它实现了两者的混合体)
- 累积确认(像GBN)
- 单个超时重传定时器(像GBN)
- 是否可以接受乱序的,没有规范
通过以下事件触发重传
- 超时(只重发那个最早的未确认 段:SR)
- 重复的确认 ( 例子:收到了ACK50,之后又收到3 个ACK50 )
首先考虑简化的TCP发 送方:
- 忽略重复的确认
- 忽略流量控制和拥塞控 制
TCP 发送方(简化版)
TCP发送方事件:
从应用层接收数据:
- 用nextseq创建报文段
- 序号nextseq为报文段首字 节的字节流编号
- 如果还没有运行,启动定 时器
- 定时器与最早未确认的报文 段关联
- 过期间隔: TimeOutInterval
超时:
- 重传后沿最老的报文段
- 重新启动定时器
收到确认:
- 如果是对尚未确认的报 文段确认
- 更新已被确认的报文序号
- 如果当前还有未被确认的 报文段,重新启动定时器
ACK7: 表示7之前的都发送了并且已经得到了确认。接下来就需要从8号开始
TCP: 重传