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:催促标志位