tcp
重传机制
形式
-
超时重传
-
概念
- 发送数据时设定一个定时器,若在指定工夫内没有收到应答报文,就会重发数据
-
产生超时重传的机会
- 数据包失落
- 确认应答失落
-
超时工夫 RTO 抉择
- 略大于 RTT
- 重传超时策略:超时工夫距离加倍
-
-
疾速重传
-
概念
- 发送方能够一次发送多个数据包,若两头的某个数据包失落了,接管方会始终回复这个失落的数据包应答报文,接管方若收到三次这个数据包的应答报文,就晓得该报文还没有被接管方收到,能够重传这个数据包
-
问题
- 因为接管方对后续的数据包也返回了失落的那个应答报文,所以发送方不晓得后续的数据包是否失落,也就不晓得应该重传失落的数据包还是把后续的数据包都重传
-
-
SACK
-
概念
- 选择性重传,解决疾速重传不晓得重传哪些报文的毛病
-
实现形式
- 在 tcp 头部“选项”字段里加一个 SACK,将缓存的地图发送给发送方,这样发送方就晓得哪些数据接管方收到了,哪些数据接管方没有收到,以便重传接管方没有收到的数据
-
参数
- 要开启 SACK,须要发送方和接管方都反对:net.ipv4.tcp_sack,linux2.4 当前默认关上
-
-
D-SACK
-
概念
- 对 SACK 的扩大,通过 SACK 通知发送方哪些数据被反复接管了
-
实现形式
- 若有发送方有反复发送数据包,会通过 SACK 通知发送方这这个数据包已被发送过
-
益处
-
发送方可能晓得是收回去的包丢了还是接管方发送的 ACK 丢了
- SACK 若告知这个包已被发送过,那么阐明是接管方发送的 ACK 丢了
-
发送方能够晓得收回去的数据包是否被网络提早了
- 发送方在提早之后会重发数据包,之前的数据包若一段时间后达到了接管方,接管方返回的应答报文中能看到该数据包曾经被接管了,是个反复的报文,阐明被网络提早了,而重发的数据包已被收到
-
-
序列号与确认应答(ACK)保障了 tcp 的牢靠传输
滑动窗口
引入起因
- 每发送一个数据都须要进行确认应答,收到了再发送下一个,效率比拟低。在窗口大小限度范畴内,能够无需期待上一个数据包应答,就能够持续发送下一个数据包
错误处理
-
累计应答
-
发送数据包失落
- 若发送方发送了一批数据包,两头的某个数据包失落,那么接管方回复应答时 ACK 会回复失落的那个数据包,这样接管方就晓得失落的数据包是哪一个,因而能够从新发送;
-
应答报文失落
- 若接管方返回的这一组数据包中,某一个应答报文失落了,只有最初一个应答报文发送胜利了,接管方就晓得这个数据包的其实是收到了的
-
窗口大小
-
tcp 头里的字段 window
- 接管方通过这个字段通知接管方本人还有多少缓冲区能够接收数据,发送方就能够依据接管方的解决来发送数据,免得导致接管方解决不过去,因而窗口的大小是由接管方决定的
-
接管方和发送方的窗口
- 接管方和发送方的窗口大小根本相等,因为发送方的窗口大小取决于接管方,当接管方解决能力快,窗口变大,通过 tcp 报文中的 window 字段通知接管方,若传输过程中呈现了提早,所以这时两个窗口大小不统一
拥塞管制
概念
- 流量管制是防止发送方填满接管方的缓存,但若因为其余主机之间的通信造成网络拥挤,会有超时和丢包产生,这样会导致重传,网络累赘会更大,进入恶性循环,所以 tcp 不能疏忽网络上产生的事,当网络产生拥挤时,它会升高数据的发送量。拥塞管制的目标就是防止发送方的数据填满整个网络
拥塞窗口 cwnd
-
发送窗口 swnd 和接管窗口 rwnd 是约等于的关系,有了拥塞窗口的概念后,发送窗口 swnd=min(cwnd, rwnd)
- 网络中没有呈现拥塞,cwnd 会增大,反之会减小
-
判断网络拥塞的办法
- 产生超时重传
-
相干算法
-
慢启动
- tcp 刚建设连贯实现,会有个慢启动的过程,一点一点进步发送数据包的数量
- 每接管到一个 ack,cwnd 大小就会加 1,初始化时,cwnd 大小为 1,即 cwnd 大小按指数级增长
-
ssthreshold,slow start thresold,慢启动门限
- 当 cwnd < ssthreshold 时,会采纳慢启动算法
- 当 cwnd >= ssthreshold 时,会应用拥塞防止算法
-
拥塞防止
- 每收到一个 ack,cwnd 减少 1 /cwnd。即囤积了 cwnd 这么多个包后,一次性发送过来。之后都会这样发送,cwnd 按线性增长
- 当始终这么增长,会缓缓进入拥塞情况,于是开始呈现丢包景象,这时须要对失落的数据进行重传,当触发了重传机制也就进入了拥塞产生算法
-
拥塞产生
-
超时重传
- ssthreshold 设为 cwnd/2
- cwnd 设为 1
- 即一旦产生超时重传就从新进入慢启动
-
疾速重传
- 当接管方发现丢了一个两头包时,会发送三次失落包的 ack,发送方收到后就会疾速重传失落的包
-
tcp 认为这时候拥塞并不重大,只丢了一小部分包,于是
- cwnd = cwnd/2
- ssthreshold 变为 cwnd
- 而后进入疾速复原算法
-
-
疾速复原
- cwnd = ssthresold+3
- 重传失落的数据包
- 如果再收到反复的 ack,那么 cwnd+1
- 收到新的 ack 后,cwnd 变为 ssthreshold,而后进入拥塞防止算法
-
流量管制
概念
- 流量管制是基于滑动窗口实现的,tcp 通过让接管方指明心愿从发送方接管的数据大小(窗口大小)来进行流量管制
问题
-
形容
- 接管方收到了太多数据,临时不能接收数据了,于是返回了 window 大小为 0
- 发送方发现 window 大小为 0,于是临时不再发送数据包了
- 接管方解决完数据,能够持续解决了,于是在之前已解决完的数据包的应答报文中更新窗口大小,然而该应答报文失落了,导致接管方没能收到,于是就始终不发送新的数据包了,呈现了死锁
-
解决办法
- tcp 为每个连贯设定一个继续计时器,只有发动连贯的一方从对方收到零窗口告诉,就启动计时器;如果继续计时器超时,就会发送窗口探测报文,对方会给出本人当初接管窗口的大小
- 窗口探测次数个别为 3 次,每次大概 30-60 秒,如果三次后窗口还是 0,有的 tcp 实现会发动 RST 报文来中断连贯
糊涂窗口综合症
-
发送方
- 发送方尽管晓得窗口很大,然而每次都只发送很少的数据
-
接管方
- 接管方太忙,每次都只能从 window 中取出很少的数据,而后告诉发送方,这样发送方每次也只发送很少的数据
-
问题
- 每次都只传输小包,效率低
-
解决办法
-
让接管方不告诉小窗口给发送方
-
当窗口大小小于 min(mss,( 缓存空间 /2)) 时,就会向发送方告诉窗口为 0,阻止发送方后续发送数据过去
- 注 mss,Maximum Segment Size,最大报文长度,MSS 是 TCP 报文段中的数据字段的最大长度,不包含 TCP 首部的长度
-
-
让发送方不发送小包
-
Nagel 算法
-
发送条件
- 等到窗口大小 >=mss 或数据大小 >=mss
- 收到之前发送数据的 ack 应答
- 满足发送条件的两点才会发送
-
设置敞开
- Nagel 算法默认开启,若想要敞开,须要在 socket 设置 TCP_NODELAY 来敞开。没有全局参数,须要每个利用依据本人的特点来敞开
-
-
-