【Linux 网络】TCP 拥塞控制与异常处理:从原理到实践的深度剖析


一、概念

少量丢包------重传就行

大量丢包------OS判定网络拥塞

一旦网络拥塞,所有主机要不发或者减少数据发送,不是直接重传,因为一旦重传,所有主机都重传,导致网络更加拥堵;所以所有主机要么不发、等等再发、减少数据发送,这时因为 TCP 构建了全网内所有主机的面对拥塞的共识,因为大家都用的是 TCP 协议;

二、如何进行拥塞控制

TCP引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;例如:先发送一个报文,如果有应答,再发两个,如果有2个应答,在发送4个报文。。。。以此类推;这个发送的报文数量是:指数增长的:2^n

拥塞窗口在 TCP/IP 协议栈中用一个 int 来表示,拥塞窗口用来衡量网络的拥塞程度,例如:拥塞窗口 = 10,如果主机单次发送数据量大于 10 此时就会可能发生拥塞,小于 10 就可能不会发生拥塞;

发送数据要考虑:1.网络,2.接收方

所以:滑动窗口 = min(对方的接收缓冲区的剩余空间,拥塞窗口);也就是:start = ack_seq,end = start + min(对方的接收缓冲区的剩余空间的大小,拥塞窗口);

那么发送方是如何控制自己的发送量的,例如:满启动?

答:直接让 拥塞窗口 = 1 ,此时根据滑动窗口 = start = ack_sq,end = satrt + min(对方的接收缓冲区的剩余空间大小,1)这样就能控制数据的发送量;但是拥塞窗口不是一致等于1的,而是动态变化的;

为什么慢启动的是指数增长(2^n)

答:这个 2^n 是前期增长慢,后期增长快,因为一旦拥塞情况经过探测,发送不怎么拥塞,那么主要矛盾变成了,尽快恢复正常通信;慢启动是可靠性和效率之间的平衡点;

指数增长不能让这个数字一直增长,指数增长没有意义,但是持续探测网络拥塞情况有意义:

当增长到 ssthresh 值时变成线性增长,第一次 ssthresh 的值为12,在线性增长的过程中,如果发生拥堵,拥塞窗口 = 1,ssthresh 值为上一次当前值的一半;

那么立马从线性增长到指数增长的那个值就是网络拥堵的临界值,它可以作为后续拥塞窗口的参考值;如果变成了线性增长,后面一直没有拥堵,那么拥塞窗口理论上是会一直在增长的、一直在探测;因为增长的本质是在探测最真实的网络拥堵窗口值,因为网络是动态变化的;但是实际上是不会一直增长的,他不会超过本地的带宽;

三、TCP 异常情况

进程终止:客户端或者服务端挂掉,此时 OS 会自动断开连接,相当于自动释放文件描述符(引用计数);

进程重启:和进程终止一样;

机器掉网 / 网线断开(面试题):只有一方断网的情况:断网的那一方通过硬件中断 OS 会自动断开连接,此时对方没有断网的可以发送消息,但是 TCP 内置自己的保活定时器,会定期询问对方是否存在(就是发送报文没有应答),如果对方不存在就会释放掉;即使没有这个保活机制,如果一方的写端或者读端关闭,此时就会触发 SIGPIPE 信号自动杀掉进程,所以我们要忽略掉这个信号,如果断网的那一方重新连上了网,此时对方也没有断开和我的连接,此时对方发送报文,此时我就会回个 reset 要求重新三次握手;因为 TCP 内置的保活机制的保活定时器的时间太长了,这就需要我们用户层自定义保活机制(时间戳);如果一方断开网,此时会触发硬件中断,OS 会自动断开所有链接;

相关推荐
budingxiaomoli2 小时前
HTTP协议
网络·网络协议·http
zbguolei2 小时前
CentOS 7.6离线安装Nginx
linux·nginx·centos
苏宸啊2 小时前
Linux开发工具(二)
linux
啊湘2 小时前
服务器维护------日志大小控制
运维·服务器·日志大小
tobias.b2 小时前
408真题解析-2010-9-数据结构-折半查找的比较次数
java·数据结构·算法·计算机考研·408真题解析
源代码•宸2 小时前
Leetcode—404. 左叶子之和【简单】
经验分享·后端·算法·leetcode·职场和发展·golang·dfs
WBluuue3 小时前
数据结构与算法:dp优化——优化尝试和状态设计
c++·算法·leetcode·动态规划
Linux技术芯3 小时前
黄益平《金融的价值》解码:从浙金中心风暴看金融风险识别与普通人理财生存指南
linux
qq_366086223 小时前
SQL Server 之 Full-Text Search 全文搜索
运维·服务器·数据库