Linux学习记录——삽심칠 传输层TCP协议(2)

news2024/9/21 22:14:53

文章目录

  • 1、滑动窗口
  • 2、拥塞控制
  • 3、延迟应答
  • 4、捎带应答
  • 5、总结TCP可靠性和性能提高
  • 6、面向字节流
  • 7、粘包问题
  • 8、异常情况
  • 9、全连接、半连接


上一篇是传输层TCP协议(1)。本篇默认读者已经清楚TCP报头各个部分、可靠性和握手挥手的含义。
有时候会把客户端写作C,服务端写作S。

1、滑动窗口

C和S之间的交互有串行的方案,一收一发;多发多收,时间会有重叠,效率更高,这是TCP通信的主流方案。对于TCP,可靠性确实重要,但效率也是其考虑的重点。发不能超过收的上限,在能收的前提下再发。一次最大发送量取决于对方窗口大小。发送方和接收方可以互换角色。

窗口大小在发送方的发送缓冲区内,滑动窗口是发送缓冲区的一部分,这部分可以不用收到应答,直接发送,当然也得对方能收得了。这样可以把发送缓冲区分成三部分,左边部分是已经确认发送了的,这部分可以被覆盖;中间是滑动窗口部分,可以直接发送但尚未收到应答;右边部分是尚未发送的数据。中间部分一旦有数据收到应答,窗口就滑动,向右滑动。滑动窗口有多大取决于对方发送的应答报文中的窗口大小。当应用层有数据写入时,比如调用write函数,就会把数据放到右边的部分。

假设把发送缓冲区当作一个char数组,因为char能访问1字节的数据,数组分出多个块。发送数据,缓冲区接收,这也就是流的概念。每个进来的数据都有下标作为序号。滑动窗口就是两个下标之间的区间,假设下标是start和end,当创窗口开始移动时,就是前后下标+±-。

在这里插入图片描述

滑动窗口不能向左滑动,因为左边是已经发送且确认的,右边是没发送的。滑动窗口取决于对方的接收能力,所以可以变大变小,变大就是end += …,变小就是start += …,变0就是对方接收缓冲区满了,两个指针指向同一个位置。

发送要按序,应答也会按序。应答报文中有两个重要字段,序号和窗口大小。序号表示这个序号之前的报文都收到了,所以start = 序号,应答报文的窗口大小win,则对应着end = start + win。应答报文不断发送,start就不断更新,以win变化或者不变化,end都向右移动,这样窗口就滑动了。

假设发送了100,200,300,400报文,如果第一个丢失,怎么办?丢失有两种情况,一个是发送出去了,而对方的ACK,也就是应答丢失了,这个没有关系,因为后续收到201报文,其实就知道100报文丢了,但能根据201报文调整窗口;另一个情况是还没发送出去,数据丢了,而不是应答丢失,比如中间的200报文没发送过去,100,300,400都收到了,这时候服务器即使收到了后面几个报文,返回的几个应答中的序号也都会写101,客户端得到重复的101后,TCP就知道丢包了,此时客户端就等待超时重传,重新发200报文,这个机制叫做高速重发或者快重传机制。而为了超时重传,为了数据没丢,服务器确认收到之前,报文都必须先保存,这里就对应上窗口根本没动,数据保存在滑动窗口,加上之前收到300,400报文,200重发后,服务器就会发送序号为401的应答,客户端就从400报文往后继续发。

无论窗口内哪个位置的报文丢包了,都不需要担心,办法就是上段所说。

窗口一直滑动,也不会越界,因为发送缓冲区可以设计成环状结构,就可以做到循环使用。这也就是为什么数据可以被覆盖。所以这里就用到了环形队列。

快重传和超时重传不冲突,共存,快重传决定重传的上限,超时重传决定重传下限。

2、拥塞控制

客户端C和服务端S之间的交互,C会发送数据到网络中,S会从网络中拿到数据,C和S不仅有各种机制,网络也有机制。网络相比于C和S复杂得多。网络里有大量发送方和接收方,网络中所有的主机或设备都在遵守TCP/IP协议。

出现错误,出现的次数多和出现的次数少的原因是不同的,比如丢包,丢的少可能是发送方问题,丢的多可能就是网络问题。当出现大量丢包时,这个问题就是网络拥塞,此时重传会加重网络负担,因为网络内所有主机都会被影响,主机都会判定网络出现拥塞,然后在短时间内大量重发数据,就会加重网络负担,加重拥塞问题。所以重传的机制都不能采用。

拥塞的原因有很多,TCP只是网络策略,没办法彻底解决网络的大部分问题。网络拥塞的解决也不能让所有的主机都等待处理,这样效率有点低。在网络拥塞有起色的情况下,要尽快恢复网络通信。

虽然有流量控制,可以尽量减少网络拥塞,但总归还是有,比如最一开始发送数据的时候。当出现网络拥塞后,拥塞控制就开始生效。TCP会先使用慢启动机制,属于拥塞控制机制,发送少量的数据探路,摸清当前拥塞状况,再决定以多少速度来传输数据。比如发一个报文,有应答就发送2个报文,有应答就发送4个报文,以此类推,发送到那个报文丢包了,就知道当前拥塞程度;如果1个报文就丢了,那就说明拥塞很严重。TCP丢包后会超时重传,还是发送丢包前发送的微量报文,等待时间就是为了等网络拥塞好转。

为了衡量网络健康状态,即拥塞状况,用拥塞窗口来当作指标。网络的状态是变化的,那么拥塞窗口大小一定也是变化的。主机要了解网络健康状态只能尝试、探测,也就是得到当前网络的拥塞窗口。发送开始的时候,定义拥塞窗口大小为1,每次收到一个ACK应答,拥塞窗口大小就加1。上面所写的滑动窗口,不仅要对端主机的接收能力,还要看网络的拥塞窗口,所以实际上滑动窗口的上限等于这两个的较小值,用min函数,对应到start和end变量,start还是序号,end则是序号 + 窗口大小,和拥塞窗口的较小值。

拥塞窗口的增长速度是指数级别的,也就是上面所说的发1个,2个,4个,8个。指数增长前期慢,后期飞速增长,这就对应着,试探网络情况时要发少量的报文,后面网络好转了就要尽快恢复正常发送。但指数增长不能一直增长下去,这里就用一个叫做慢启动,也叫ssthreah的阈值,超过阈值就变成线性增长。指数增长到线性增长的整个过程,一直在探测拥塞窗口。当增长超过一次拥塞窗口时,就直接从1开始,重新指数增长,而这一次的阈值变为上一次拥塞窗口的一半,之后不断进行同样的做法。这样的循环会一直循环下去。

3、延迟应答

为了让发送和接收的效率提高,接收方可以给发送方更大的窗口大小。虽然滑动窗口大小还有拥塞窗口在制衡,但如果不给更大的,发送方就不可能在同一时间发送更多的数据,给更大的窗口大小才有这个概率。接收方要给,就得自身接收缓冲区剩余空间更大才行,接收缓冲区的清理取决于上层应用层,要想让应用层更快地读取数据,可以不需要立马应答,发送方还有超时重传机制,在未超时前,接收方等待一下,给应用层更多时间,让应用层多读取一些数据再给应答,这就是延迟应答。

延迟应答可以利用时间等待来应答,也可以每隔几个包再应答一次。一般每隔2个包,或者等待不超过200ms。

4、捎带应答

这个在之前的博客中写过,也就是一次性多发几个报文,不占用效率反而提高效率。有些报文不需要单独发一次,所以就在发送一个报文时,顺便带上这些报文。

5、总结TCP可靠性和性能提高

可靠性:

检验和(校验和),序列号,确认应答,超时重发,连接管理,流量控制,拥塞控制

提高性能:

滑动窗口,快速重传,延迟应答,捎带应答

TCP还有定时器,比如超时重传定时器,保活定时器,TIME_WAIT定时器等。

6、面向字节流

TCP有发送缓冲区和接收缓冲区,应用层发给传输层的数据,是以字节为单位发送的,数据可以拆分成几个字节为一组。数据统统发给TCP后,TCP存在发送缓冲区右边部分,通过滑动窗口,一块块地发送到对端主机的接收缓冲区内。这也就是面向字节流,发送接收都已字节为单位。无论上层怎样读取发送,TCP都以字节为单位来相互拷贝。

下层如何发送接收,失败成功,上层并不关心,每层做每层的事,每层只关心这一层,这也就是流。

7、粘包问题

TCP是被上层使用套接字进行访问的,TCP使用的数据都是上层发送过来的,不过因为面向字节流,TCP并不知道这些数据,而上层知道,那么TCP如何保证读到的是完整报文?读一个完整的或者读多个完整的,但每一个都分开,这种读取完整报文就是粘包问题,也叫做粘包问题。在之前的代码实现中,可以循环读取,每次读取都做解析,分成各个成员。

计算机解决粘包问题有很多办法,比如定长包,分割符,报头加相关信息等,不过本质上这个问题的解决就是明确两个包之间的边界。UDP没有这个问题,因为UDP报文的长度都能够在报头中知道,且因为UDP报文需要处理。TCP中没有有效载荷长度,两个TCP报文之间的分离,是由应用层自主完成的,TCP报文不做处理,就是存储在缓冲区内。

8、异常情况

一个进程运行时申请了很多资源,在还没处理好资源,没有关闭像malloc,fd这样的时候,进程终止,这时候内存泄漏不存在,因为进程挂了,就由bash管理所有资源,页表,地址空间等等,也就是被回收了。网络这里也是这样,建立的连接都是OS做的,无论是否异常断开,OS都会进行挥手再断开,由OS决定。异常断开,比如拔网线,拔了之后,服务器不知道客户端断了连接,以为还有连,服务器也有保活策略,隔一段时间发去报文询问,如果没有应答服务器就断掉连接。如果刚拔又插上,可能服务器只发过一次保活信息,客户端因为断开过连接,但是它自己又不知道,接到保活信息才知道自己以前的某个连接异常,就会发送RST报文让服务端重置连接。

TCP的连接长短是由应用层做的。活跃连接是经常交互的连接,这个好管理;如果建立一个长连接,但不怎么交互,但却要一直挂着连接,不能断,这样的连接维护起来成本比较高点,如果这时候TCP插手关掉连接,那么对应用层就有不好的影响,但长时间挂着TCP又得不断询问。所以实际上,连接的维护是由应用层来做的,保活一般以小时为单位。

9、全连接、半连接

三次握手,客户端第一次发送过去SYN,服务器发送SYN + ACK应答后服务器处于SYN_RECV状态,这是半连接状态。TCP协议需要在底层维护全连接队列,队列长度就是listen接口第二个参数 + 1。假设第二个参数为1,此时只能由两个连接成功,成为全连接状态,其它再发送请求时,服务器只能处于SYN_RECV状态,这些半连接状态的连接就会被维护在半连接队列中,维护的时间很短,这个时间就是在等待上层把全连接的连接取走。全连接是指已经连接成功,但还没被应用层读取的连接。半连接队列不能太长,效率低了且不如增大-长全连接队列或者增加服务器吞吐量,会过多消耗OS本身的资源,客户端也不愿意等。

结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1367169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《中学物理奇妙日志——30天物理学探索之旅》提纲

《中学物理奇妙日志——30天物理学探索之旅》提纲 第一部分:物理学基础(第1-5天) 第一天:引言 - 从生活中的物理现象出发,阐述物理学的定义与重要性 子主题:物理学的历史、发展及在现代生活中的广泛应用 …

Postman Newman 教程:轻松管理 API 自动化测试步骤

Postman 中的 Newman 是什么? Newman 是一个 CLI(命令行界面)工具,用于运行 Postman 中的集合(Collection)和环境(Environment)来进行自动化测试。它允许直接从命令行运行 Postman …

不求人,自己找到全网最火的编程项目。

文章目录 一. 到哪儿去找项目?二. 什么是最好的项目?三. 怎么高效找项目?四. 怎么高速下载项目? 一. 到哪儿去找项目? 书上习题网络课程线下培训Github、Gitee、开源中国 最好的找项目的地方是github。 二. 什么是最…

【读书笔记】网空态势感知理论与模型(七)

通过网络级对象依赖关系揭示0Day攻击路径 1. 研究动机 0Day攻击是攻击者和防御者之间信息不对称的结果。赛门铁克研究人员认为,典型的0Day攻击平均隐藏312天才会被觉察。 受到SKRM模型启发,Patrol系统以全局视野来调查在某一个路径上的0Day攻击行为。从…

Redis中字符串表示是如何设计与实现的?

文章目录 Redis中字符串表示是如何设计与实现的(SDS)?引言简单动态字符串底层数据结构为什么不用char *举个🌰如何优化append操作?总结 Redis中字符串表示是如何设计与实现的(SDS)? …

Tomcat 的 work 目录缓存导致的JSP页面图片更新问题

一、问题分析 1. 修改后重新部署没有变化 笔者之前部署了一个后台管理项目,通过它来发布课程内容,其中有一个 JSP 课程页面,在该 JSP 页面里也引用了类文件 Constant.java 里的一个变量(ALIYUN_OSS_PATH),…

7个PyCharm实用插件实现轻松编程

大家好,IDE(集成开发环境)是开发者的武器,使用一个好的IDE和一些很棒的插件,工作效率会更高。Python是一种广泛使用的编程语言,PyCharm是最受欢迎的Python IDE之一。以下介绍7个PyCharm插件,它们…

JavaScript基础(25)_dom查询练习(二)

<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><title>dom查询练习二</title><link rel"stylesheet" href"../browser_default_style/reset.css"><style>form {margi…

K8S--持久卷(PersistentVolume)的用法

原文网址&#xff1a;K8S--持久卷(PersistentVolume)的用法-CSDN博客 简介 本文介绍K8S的持久卷(PersistentVolume)的用法。 目标&#xff1a;用持久卷的方式将主机的磁盘与容器磁盘映射&#xff0c;安装nginx并运行。 --------------------------------------------------…

IO流-文件复制

IO流 概述&#xff1a;IO流&#xff0c;输入输出流&#xff08;Input Output&#xff09;流&#xff1a;一种抽象的概念&#xff0c;对数据传输的总称。&#xff08;数据在设备之间的传输称为流&#xff09;常见的功能 文件复制文件上传文件下载 学习流&#xff0c;我们要搞懂…

CSS 发光输入框动画

<template><view class="content"><input placeholder="请输入..." class="input" /> </view> </template><script></script><style>/* 设置整个页面的背景颜色为 #212121 */body{background-c…

centos7系统部署SqlServer2019

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 一 关于SQL Server SQL Server数据库是Microsoft开发设计的一个关系数据库智能管理系统(RDBMS)。 二 安装部署 2.1 安装依赖 …

使用 matlab 求解最小二乘问题

有约束线性最小二乘 其标准形式为&#xff1a; min ⁡ x 1 2 ∥ C x − d ∥ 2 2 \mathop {\min }\limits_x \quad \frac{1}{2}\left\| Cx-d \right\|_2^2 xmin​21​∥Cx−d∥22​ 约束条件为&#xff1a; A ⋅ x ≤ b A e q ⋅ x b e q l b ≤ x ≤ u b \begin{aligned} …

linux创建pyspark虚拟环境

一、创建虚拟环境 conda create -n test python3.6.6 二、注意添加镜像 vi /root/.condarc channels:- http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/- http://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/- http://mirrors.ustc.edu.cn/anaconda/pkgs/ma…

消息队列-RockMQ-批量收发实践

批量收发实战 发送消息是需要网络连接的如果我们单条发送吞吐量可能没有批量发送好。剖来那个发送可以减少网络IO开销&#xff0c;但是也不能一批次发送太多的数据&#xff0c;需要根据每条消息的大小和网络带宽来确定量的数目。 比如网络带宽为可以支持一次性发送8M的数据包&…

如何解读服务器的配置和架构?

在当今数字化时代&#xff0c;服务器作为企业或组织的重要基础设施&#xff0c;其配置和架构对于保障业务的稳定运行至关重要。如何解读服务器的配置和架构&#xff0c;成为了一个备受关注的话题。本文将围绕服务器配置和架构的解读进行深入探讨&#xff0c;帮助读者更好地理解…

DDIM学习笔记

写在前面&#xff1a; &#xff08;1&#xff09;建议看这篇论文之前&#xff0c;可先看我写的前一篇论文&#xff1a; DDPM推导笔记-大白话推导 主要学习和参考了以下文章&#xff1a; &#xff08;1&#xff09;一文带你看懂DDPM和DDIM &#xff08;2&#xff09;关于 DDIM …

如何精选WordPress插件

WordPress的强大功能大多得益于其众多插件。正确选择插件可以让你的网站功能强大、运行平稳&#xff0c;而错误的选择则可能导致网站变慢甚至出现安全漏洞。这篇文章将指导你如何在众多可选的插件中作出明智的选择。 明确需求 在浏览WordPress的插件目录或其他市场之前&#…

阶段十-分布式-任务调度

第一章 定时任务概述 在项目中开发定时任务应该一种比较常见的需求&#xff0c;在 Java 中开发定时任务主要有三种解决方案&#xff1a;一是使用JDK 自带的 Timer&#xff0c;二是使用 Spring Task&#xff0c;三是使用第三方组件 Quartz Timer 是 JDK 自带的定时任务工具,其…

STL标准库与泛型编程(侯捷)笔记1

STL标准库与泛型编程&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youbute: 侯捷-STL标准库与泛型编程 B站: 侯捷 - STL Github:STL源码剖析中源码 https://github.com/SilverMaple/STLSourceCo…