TCP的特性(4)

TCP特性

拥塞控制(可靠性机制)

虽然TCP引入了滑动窗口,能够高效可靠的传输大量数据,但是在开始阶段就发送大量数据,可能引起一系列问题.

TCP引入了慢启动机制,先发少量的数据,判断当前的网络拥堵状态后,再决定按照多大的速度传输数据.

"拥塞窗口": 在拥塞控制机制下,采用的窗口大小.

  1. 慢启动: 刚开始进行通信时,会使用非常小的窗口,探探路.
  2. 指数增长: 在传输通畅的条件下,拥塞窗口会指数型增长.
  3. 线性增长: 当指数增长到一个阈值后,就会从指数增长转变为线性增长.
  4. 拥塞窗口回归小窗口: 在窗口增大的过程中,如果传输出现丢包,认为当前网络出现拥堵了,
    此时就会把窗口大小调整为最初的小窗口,继续进行指数增长->线性增长的过程,会根据刚才
    丢包的窗口大小,调整阈值.

当出现网络拥堵(丢包)后,把丢包窗口大小 / 2变为新的阈值,拥塞窗口就是在这个过程不断发生变化,

在权衡之下,我们实际发送的窗口大小为 = min(拥塞窗口, 流量控制窗口).

拥塞控制和流量控制共同限制了滑动窗口机制,可以使滑动窗口在保证可靠性的前提下,提升效率了.

延迟应答(效率机制)

我们是否有办法在条件允许的基础上,尽可能的提高窗口大小呢?

延迟应答就向我们挥手了, 可以在接收方返回ACK的事后,拖延一下,利用拖延的时间尽可能的消费接收缓冲区的数据,这样接收缓冲区剩下的空间就会更大了.

通过延迟应答的方式,提高的速度取决于接收方实际的处理数据的能力,如果在拖延的时间里你还是没有处理更多数据,那么延迟应答带来的提升就会很小.

也不是所有的包都会出发延迟应答:

  1. 滑动窗口(数量限制): 每隔N个包就应答一次.
  2. 非滑动窗口(时间限制): 超过最大延迟时间就应答一次.

捎带应答(效率机制)

在延迟应答的基础上,引入了进一步提升效率的方式.

延迟应答: 让ACK传输的更慢.

捎带应答: 基于延迟应答,使数据合并

这是没有捎带应答的方式:

这是带有捎带应答的方式:

加入捎带应答后,两条效用合并了,这也是四次挥手也可能是三次的原因,主要是捎带应答和延迟应答起到的效果.

面向字节流(粘包问题)

这里用一个经典问题("粘包问题").包: 应用层数据报

发送方可以一次性发送很多应用层数据报,但是在接收的时候,如何区分呢?

此时不是传输层的问题,而是站在应用层的角度解决这个问题:

  1. 应用层协议中,引入分隔符,区分包的边界.

接收方就可以按照\n区分应用层数据报的边界了.

  1. 应用层协议中,引入包长度,区分包的边界.

根据长度读取数据.

粘包问题不仅仅是TCP独有的,面向字节流机制的都用同样的问题,就可以引入分隔符和长度来解决.

xml / json是根据分隔符来区分的,protobuffer是根据长度来区分的.

TCP异常机制

  1. 进程崩溃:
    进程结束 -> PCB没了 -> 文件描述符表释放了 == socket.close().
    崩溃的一方会发出FIN -> 四次挥手 -> 连接正常释放了.
  2. 主机关机:
    正常关机后,会尝试终止所有进程,和进程崩溃时一样的处理结果.但是当接收方的FIN发过来是,请求方已经关机了,接收方收不到ACK就会重传FIN,连续尝试几次后都没有收到ACK,就单方面释放了.
  3. 拔掉电源:
  • 接收方正给发送方发消息:
    接收方收不到ACK就会重传FIN,连续尝试几次后都没有收到ACK,就单方面释放了.
  • 发送方正给接收方发消息:
    接收方在等待发送方的消息,至于等多久我们是不知道的,这里就涉及到心跳包 .
    虽然是接收方,长时间收不到数据,也会周期性的给发送方发一个不带任何业务的TCP数据报,就是为了确认发送方是否正常工作/确认网络是否畅通.
  1. 网线断开:

此时发送方和接收方就无法通信了,有两种情况

如果是发送方断了,就是拔掉电源的接收方正给发送方发消息 的情况.

如果是接收方断了,就是拔掉电源的发送方正给接收方发消息的情况.

小结

结合前面几篇博客,一共总结了TCP特性中的10个.

  1. 确认应答(可靠性核心机制)
  2. 超时重传(可靠性机制)
  3. 三次握手和四次挥手(可靠性机制)
  4. 滑动窗口(效率机制)
  5. 流量控制(可靠性机制)
  6. 拥塞控制(可靠性机制)
  7. 延迟应答(效率机制)
  8. 捎带应答(效率机制)
  9. 面向字节流(粘包问题)
  10. TCP异常情况(心跳包)

希望有收获的小伙伴多多支持!

相关推荐
哎呦没22 分钟前
SpringBoot框架下的资产管理自动化
java·spring boot·后端
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
姑苏风3 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
测开小菜鸟6 小时前
使用python向钉钉群聊发送消息
java·python·钉钉
数据猎手小k7 小时前
AndroidLab:一个系统化的Android代理框架,包含操作环境和可复现的基准测试,支持大型语言模型和多模态模型。
android·人工智能·机器学习·语言模型
P.H. Infinity7 小时前
【RabbitMQ】04-发送者可靠性
java·rabbitmq·java-rabbitmq
生命几十年3万天7 小时前
java的threadlocal为何内存泄漏
java