网络原理(4)-TCP ▲▲▲

1.拥塞控制

和流量控制类似,都是对滑动窗口做出限制。

拥塞控制依据通信链路的处理能力。网络传输除了发送端和接收端,中间路径还涉及许多设备。

1.拥塞控制是用来干啥的?

网络传输的中间路径(路由器、交换机)可能发生拥塞、缓存溢出、丢包等,甚至网络瘫痪。

拥塞控制就是用来防止【发送端发送太快,把整条网络链路堵死】,限制拥塞窗口,不超过网络当前的承载能力。

2.拥塞窗口cwnd(Congestion Window)

拥塞窗口是用来防止网络发生拥塞的窗口,它代表网络当前允许发送到网络中的最大数据量。

拥塞窗口越大,传输速率越大;拥塞窗口越小,传输速率越小。

3.拥塞窗口的变化规律

纵坐标代表的不是实际大小,单位窗口实际大小乘以纵坐标才是真实大小。

当TCP开始通信后,

1.初始情况下,拥塞窗口从1开始,这是一个慢启动。

2.然后指数增长,每轮窗口大小翻倍

3.窗口大小到达阈值ssthresh(Slow Start Threshold慢启动界限),窗口大小变为线性增长

4.线性增长到了一定程度(最大窗口),就可能触发丢包

5.丢包之后,就会改变拥塞窗口大小,这里有两个方案:

(1.)Tache版本(已废弃)。拥塞窗口直接回到初始值1,ssthresh变为(最大窗口值/2)。然后拥塞窗口开始指数增长,增长到ssthresh后继续线性增长。

(2.)Reno版本。ssthresh变为(最大窗口值/2),拥塞窗口大小变为ssthresh,然后继续线性增长。

4.拥塞机制是基于滑动窗口才有的机制

滑动窗口批量传输大量数据,可能造成丢包、阻塞等情况,所以有了流量控制和拥塞控制。

5.TCP发送窗口,取流量控制的接收窗口rwnd和拥塞控制的拥塞窗口cwnd选择最小值。

TCP真正能发送多少数据,要同时满足两个限制:

不能超过接收方的缓存上限rwnd

不能超多网络承载的上线cwnd

2.延时应答

目的:提升传输效率。

基于滑动窗口,尽可能把窗口变大。所以就有了延时应答机制。

1.延时应答机制怎么作用是的传输效率提升的?

我们都知道接收方有一个接收缓冲区------》发送方是怎么知道每次要发的数据上限(上限就是接收缓冲区的剩余空间大小)是多少呢?------》发送方每发送一个数据,接收方都返回一个ACK,ACK报头的"16位窗口大小"里就存着接收缓冲区的剩余空间------》发送方收到ACK,知道了接收缓冲区的剩余空间------》调整这次发送的数据。

而上述一次发送一次ACK的机制是可以优化的:

接收方收到一个数据不立即返回ACK,而是延迟,等应用程序处理一些数据后,接收缓冲区的剩余空间就更大,此时再返回一个ACK。

应用程序处理的数据越多,后续发送的数据就越快。

3.捎带应答

捎带应答配合延时应答。

网络通信中常见模式是:

而捎带应答是:

服务器计算请求是需要时间的,如果计算的时间很快、并且赶上了延时应答,就可以把ACK和响应合成一个数据包返回给服务器。

4.面向字节流粘包问题

面向字节流传输的过程中,可能涉及到粘包问题。

接收方和发送方都可能涉及到粘包问题。

接收方:

接收方接收发送发发来的两个TCP报文,分别是:"hello","world",

但是接收方应用程序调用receive时读取数据的时机慢了,两个报文都已到达接受缓冲区,当receive时直接把缓冲区的全部数据都读出来,读到合并后的字符串,分不清边界。

发送方:

发送方调用send2次,发两端独立的业务数据"hello","world"

如果数据包很小,TCP默认不会立刻把小包发送出去,会把多个小数据攒到一起,合并成一个TCP报文段发给对方。

接收方读到的是"helloworld",分不清是两条消息。

UDP是面向报文的,不涉及粘包问题。

5.异常情况

1.进程崩溃

和四次挥手关闭连接完全相同。

正常的四次挥手:通过调用socket.close()触发。

进程崩溃:操作系统自动对文件资源进行释放,操作系统清理PCB、PCB中的文件描述符表=等价于调用socket.close()。

2.主机关机(正常流程关机)

代表先强制结束所有运行的应用程序,然后再关机。

强制结束应用程序就相当于进程崩溃,所以也会触发四次挥手。

关机了四次挥手也已经挥完;

但是,如果关机了四次挥手还没完,情况是这样的:

服务器多次重传FIN后,仍然没有收到ACK,服务器就会单方面放弃连接,把自己持有的客户端信息就删了。

3.主机关机(突然断电关机)

程序来不及进行任何挥手操作!

接收方断电

发送端给接收端发送数据包,接收端断电;

发送端一直收不到对面的ACK,

发送方超时重传,

经过几次重传后,仍收不到ACK,

发送方放弃连接,删除对方的信息。

心跳包-发送端断电

接收端只能感知到对方无回应了,但是不知道对方是挂了还是暂停一会,稍后继续。

所以接收端周期性的给对方发一个"心跳包",这个数据报不携带业务,只是为了触发一次ACK,如果几次之后对方没有ACK,接收端就会铸锻都拿开连接。

4.网线断开

接收方周期性给发送方发送"心跳包",如果对方挂了,接收方主动断开连接。

发送方收不到ACK,超时重传几次后仍收不到,发送方主动断开连接

5.对于异常情况的处理

1.四次挥手

2.不能挥手,如果对方主机可达但无连接记录,对方回复rst,本地再断开连接;

如果对方主机断电,本地主动释放连接。

3.通过心跳包感知对方的状态

6.补充

URG:紧急指针有效

PSH:催促标志位

相关推荐
雨辰AI1 小时前
信创多租户项目 9 大踩坑|数据隔离失效、权限越权终极解决(金仓 / 达梦 / 高斯全库适配)
java·大数据·数据库·后端
橙子圆1231 小时前
JUC之线程和进程
java
Bs_MoneyMagnet1 小时前
基于springboot+vue的旅游行程分享与推荐小程序的设计与实现 源码+文档
java·vue.js·spring boot·后端·微信小程序·毕业设计·计算机毕业设计
代码中介商1 小时前
C++ 预约系统实战(二):TCP + JSON 自定义协议设计
c++·网络协议
一技安身1 小时前
【信创】统信UOS 银河麒麟离线部署Python3.11完整方案
android·java·python3.11
溪语流沙1 小时前
【Python项目实战】部署上线:把博客发布到云服务器
服务器·开发语言·python
渡我白衣1 小时前
Util工具类功能设计与类设计
linux·服务器·网络·c++·人工智能·目标检测·机器学习
小此方1 小时前
Linux网络(十一):HTTP重定向与请求方法详解:从301/302状态码到GET/POST,再认识Fiddler抓包
linux·网络·http