终于到TCP了,这个咋看咋好的协议。
简单来说,TCP 充分地实现了数据传输时各种控制功能,丢包可以重发控制,乱序可以改正。而这些在 UDP 中都没有。
之前已经知道了,UDP协议采用的是数据包的方式传送,后发出的数据包可能早到,我们并不能保证数据到达的次序。而TCP协议解决了这个问题。当计算机从TCP协议的接口读取数据时,这些数据已经是排列好顺序的“流”了。
Overview
- point-to-point,点到点
- 一个发送方,一个接收方
- 可靠、按顺序的字节流
- no“message boundaries”
- UDP面向报文包,TCP则没有这个概念,面向的是数据流
- 流水线pipelined
- 实现了之前说过的流水线控制,TCP拥堵和流控制可以设置窗口大小
- “全双工(full duplex)”data (即可以边发边收、双向传输)
- MSS: maximum segment size
- 面向连接
- 终于可以解释下这个,其实就是:只有在确认通信对端存在时才会发送数据,从而可以控制通信流量的浪费
- 实现方式是在数据交换之前,发送者和接收者之间的、handshaking(交换控制信息)
- 流控制
- 发送方不会淹没接收方,也就是不会一下子发过多到爆之类的
TCP段的overview——TCP header
TCP协议封装到IP包的不是整个文本流,而是TCP协议所规定的片段(segment)。
与之前的一个IP或者UDP数据包类似,一个TCP片段同样分为头部(header)和数据(payload)两部分
“片段”这个名字更多是起提醒作用:嘿,这里并不是完整的文本流。
它标记了相当多重要的信息,顺便能提醒你这一层的传输基于端口,提醒你他是可靠地等等
整个TCP段的结构如图所示
- 背下来
- 记得注意大小,比如16bits 源端口,16bits目标端口
一些解释:
- 序号:sequence numbers,段数据中第一个字节的在整个字节流中“编号”,用来标明位置
- 确认号:acknowledgements,期望从另一方收到的下一个字节的序号(cumulative ACK),一会儿看图就知道是啥了
Q: 接收器如何处理无序段
A: TCP规范没有说,-由编写TCP代码的人决定,只要数据交付到应用层
给我看图!!!
- 实际运⽤中一次可能不止传一个字节, Ack的顺序可能会跳
自我进化的TCP超时控制——对往返时间的估计与趋近【重要】
问题的起源
到了现实,怎么定义超时就成了个大问题——谁都知道要比往返时间(round trip time, rtt, 不记得的回去复习上一节)长,但问题是我连RTT都不知道啊??这玩意会变啊
- 超时时间timeout太短了的话,我就要不停的重发,甚至可能直接就接不到
- 太长了丢了就要等一百万年
所以,我们需要个方法来估计RTT
RTT的估计方法【重要】
- RTT的值每次都不一样,我们需要让他更趋向于一个概率上的期望值
Jacobsen/Karel's Algorithm
- 这样概率通过加权a移动,像极了机器学习
- 过去样本的影响呈指数快速降低
- 常用 a=0.125
timeout时长的设置
算出了RTT,我们可以把timeout超时时间设定为
EstimatedRTT + 一个控制的 safety margin值
先算出sampleRTT和EstimatedRTT的差值为
可靠的TCP
可靠传输理论学了一整节,终于能看看TCP具体是怎么实现它的
当收到了应用发来的数据
- 拆segment,让每一segment都有编号sequence numbers
- 编号是段中第一个数据字节的字节流
- 还没开始前就发个计时器(相当于第一个发送的段oldest unacked segment),周期为刚算出来的TimeOutInterval
如果超时
- 重传导致超时的这个段,重启计时器
如之前还没被确认过的段被确认了
- 标记它被确认了
- 还有没被确认的段的话,启动计时器,继续传
还是直接看图好了!(TCP重传方案图解)
基本都能轻松解决!
快速同传方案
有时候timeout还是太久了,其实可以提前判断
通过重复的ACK来检测报文段丢失
- 发送方通常连续发送大量报文段
- 如果报文段丢失,通常会引起(收到)多个重复的ACK
则,如果发送方收到同一数据的3个冗余ACK
- 重传最小序号的段:
第一个是正常的,后面仨重复就重传!
题目
最后一题发送窗2未确认没法右移