4.滑动窗口(效率机制)
上篇博客讲到的确认应答/超时重传/连接管理都是安全机制,但也会降低传输效率。滑动窗口就是在保证可靠传输的基础上,尽可能地提高传输效率。
根据确认应答机制,客户端每发送一个请求都需要收到服务器的确认应答报文后才会传输发送下一条请求。
4.1原理介绍
既然这样一发一收的方式性能较低,那么我们一次发送多条数据,就可以大大的提高性能(其实是将多
个段的等待时间重叠在一起了)
窗口大小:无需等待确认应答还可以继续发送请求的最大值,例如上图可以连续发送4个请求而不需要ACK,那么窗口大小就是4
发送缓冲区:既然是一次性发送多个请求,那么操作系统会维护一个发送缓冲区来统计哪些数据没有被应答
4.2丢包处理
问题1:如果ACK丢包了,怎么办?
答案:ACK丢包问题不大。例如,服务器返回了ACK(4001),表示前4000序列号的数据已经被接收,即使ACK(1001,2001,3001)都丢包也没啥影响。ACK全部丢失的情况几乎不会发生,因为正常情况下丢包本身就是小概率时间,更何况全部丢包。
问题2:如果数据(2001~4000)已经被接收,而数据(1 ~ 1000)一直没有到达,此时窗口会向后滑动吗?
答案:不会。此时服务器会重复发送ACK(1001)来向客户端索要数据,当ACK(1001)的返回次数超过一定阈值时,客户端会认为数据(1~1000)不是卡在半路,而是丢包了,客户端会重新发送数据。
这叫做快速重传机制
5.流量控制&拥塞控制(安全机制)
5.1流量控制
接收方处理数据的速度是有限的。如果发送方发的太快,导致接收方的缓冲区被打满,这个时候如果发送方继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应
因此TCP支持根据接收方的处理能力,来决定发送方的发送速度。例如,接收方数据缓冲区的大小还剩3000字节,那么接收方会将ACK中的窗口部分设置为3000,告诉发送方你应该将滑动窗口的大小设置为3000
这就叫做流量控制机制
5.2拥塞控制
网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。
TCP引入慢启动机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据
流量控制&拥塞控制区别以及谁来决定窗口大小
流量控制是根据接收方的实际情况来反馈窗口大小;而拥塞控制是根据网络的拥塞情况来反馈窗口大小。取两种机制的最小值作为滑动窗口的大小
6.延时应答(效率机制)
如果接受方收到请求后就立刻返回ACK,此时接受发的数据缓冲区的剩余空间可能比较小,那么ACK的窗口大小就比较小。我们不妨让ACK稍作等待再返回,这时候接受方已经处理掉部分数据了,缓冲区的剩余空间就大一些,ACK返回的窗口大小就可以大一些。这样做是为了让发送方可以一次性发送更多的数据,提高传输效率。
至于具体ACK延时多久才返回,每个操作系统设置的阈值不同。
7.捎带应答
在延时应答的基础上,ACK可以携带接受方的响应数据一起返回
这样的好处是减少纯ACK的返回次数
当然,如果这段时间内实在没有可以携带的数据,ACK也不可能一直等到有数据才返回,而是独自返回
8.粘包问题
这不是TCP协议独有的问题,而是所有面向字节流的协议都会有的问题。
假设发送方的滑动窗口大小是10000字节,虽然发送方是1000字节为单位进行发送,但这些数据到达接受方的数据缓冲区后,仍然会揉在一起。这时候就需要区分出多少个字节是一个完整的应用层数据包。
那么如何避免粘包问题呢?归根结底就是一句话,明确两个包之间的边界
1.对于定长的数据包,每次按照固定长度读取即可
2.对于变长的数据包,可以在包头的位置,约定一个包总长度的字段,从而就知道了包的结束位置
3.对于变长的数据包,还可以引入特殊符号作为分界线(可以参考我的TCP服务器代码Java EE(13)——网络编程——UDP/TCP回显服务器)
9.异常情况处理
9.1进程崩溃
会进行正常的四次挥手,没啥问题
9.2主动关机
关机之前系统会强杀进程,此时也会触发四次挥手,但四次挥手未必能执行完毕
(1)四次挥手执行完毕,没啥问题
(2)四次挥手没执行完毕
服务器收到FIN后会返回ACK,然后再返回FIN,只不过这个FIN将不会得到客户端的回应。那么服务器就会重传FIN,重传一定次数后依然没有结果,服务器会单方面结束连接
9.3瞬间断电
(1)接收方断电
发送方发现没有ACK了。就会进行超时重传,依然没有ACK的话,就会进行"复位连接"
复位连接的意思是,发送方和接收方的所有数据全部重置(不会再次进行三次挥手)
复位连接依然没有结果,就会单方面结束连接
(2)发送方断电
接收方本来就在等待发送方发送数据,但迟迟没有数据发送过来,接收方就会发送一个"心跳包"(心跳包是周期性发送的没有实际数据的包)来询问发送方的状态,如果判定对方没有"心跳",就会进行复位连接,然后单方面断开连接
9.4网络断开
断电是一方存在,一方不存在
网络断开是两方都存在,那么发送方会经历上述发送方断电的过程;接收方会经历接收方断电的过程