TCP的安全和效率机制

news2024/11/18 3:21:24

目录

0.TCP协议格式

​编辑

一.确认应答(安全机制)

二.超时重传(安全机制)

1.SYN丢包

 2.ACK丢包

三.连接管理(安全机制)

1.三次握手建立连接

​编辑

2.四次挥手断开连接

3.建立和断开连接

四.滑动窗口(效率机制)

五.流量控制(效率机制)

六.拥塞控制(安全机制)

七.延迟应答(效率机制)

八.捎带应答(效率机制)

九.面向字节流

1.粘包问题

2.具体的现象

 3.解决方案

1.在消息末尾加上特殊的分隔符来标识消息的结束

2.使用一个专门用来描述消息体长度的字段,来标识消息体的具体长度

十.TCP异常情况

1.程序崩溃 

2.正常关机

3.主机掉电操作

4.网线断开

十一.常见面试题


0.TCP协议格式

 传输层协议

  1. /目的端口号:表示数据是从哪个进程来,到哪个进程去;
  2. 32位序号/32位确认号:后面详细讲;
  3. 4TCP报头长度:表示该TCP头部有多少个32bit(有多少个4字节);所以TCP头部最大长是
  4. 15 * 4 = 60
  5. 6位标志位: 
    URG :紧急指针是否有效
    ACK :确认号是否有效
    PSH :提示接收端应用程序立刻从 TCP 缓冲区把数据读走
    RST :对方要求重新建立连接;我们把携带 RST 标识的称为 复位报文段
    SYN :请求建立连接;我们把携带 SYN 标识的称为 同步报文段 FIN :通知对方,本端要关闭了,我们称携带 FIN 标识的为 结束报文段
  6. SYN:请求建立连接;我们把携带SYN标识的称为同步报文段FIN:通知对方,本端要关闭了,我们称携带FIN标识的为结束报文段
  7. 16位窗口大小:后面再说
  8. 16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的检验和不光
  9. 包含TCP首部,也包含TCP数据部分。
  10. 16位紧急指针:标识哪部分数据是紧急数据;
  11. 40字节头部选项:暂时忽略;
TCP 对数据传输提供的管控机制,主要体现在两个方面:安全和效率。
这些机制和多线程的设计原则类似:保证数据传输安全的前提下,尽可能的提高传输效率。

 

一.确认应答(安全机制)

如果我们给一个人发送多条信息,由于网络的问题,可能会出现,乱序的问题.比如我们发送两条信息:1.你好.2.吃了吗? 由于网络问题,可能会出现接收方先接受到了"吃了吗?",后接受到了"你好.",这样的情况我们是不想出现的,因此确认应答机制可以很好的解决这种问题.
 

 如下图,为了解决这种问题,每次发送消息的时候,TCP数据中的字节进行了编号,比如主机B接受到了1-1000byte的数据,32位序列号中1-1000标志已经接受到了1000个字节,确认序列号返回1001,表示下次从第1001个字节进行发送.

 TCP将每个字节的数据都进行了编号。即为序列号。

每一个 ACK 都带有对应的确认序列号,意思是告诉发送者,我已经收到了哪些数据;下一次你从哪里开始发。

每次发消息的时候将SYN置为1

每次接受消息确认的时候,将ACK置为1

二.超时重传(安全机制)

1.SYN丢包

主机A发送数据(SYN)给主机B,可能由于网络拥挤等原因,消息无法到达主机B,因此主机B也不会给主机A发送确认应发ACK.如果主机A特定时间内没有接收到主机B发送来的确认应答ACK,就会将上次的数据进行重发

 2.ACK丢包

主机B接受到了主机A的数据,并且发送了确认应答ACK,但是由于网络拥堵等原因,ACK发送了丢包,主机A并没有主机B发送来的ACK应答.

这个时候也会触发超时重传机制.由于我们发送的消息主机B已经接受到了主机A发送的数据,只不过ACK应答丢包.主机B没有必要存储重复的数据,因此第二次发送消息的时候(超时重传),可以利用前面提到的序列号(前面一次发送序列号已经保存,第二次发送的时候已经存在这个序列号了),就可以很容易做到去重的效果,主机B只需要发送一个确认应答的ACK就可以了.

三.连接管理(安全机制)

在正常情况下, TCP 要经过三次握手建立连接,四次挥手断开连接

1.三次握手建立连接

对于网络通信来说,三次握手可以检查双发的收发能力是否正常,例如高铁每天都会空跑一趟.

从下图可以看出,通过两次SYN和ACK的过程可以确保双方的收发能力都没有问题,在这个基础上就可以进行正常的数据发送和接收

由于接收方的ACK和SYN可以合并为一次通信完成(都是在传输层进行发送,在后面的捎带机制也有讲解),提高了效率,四次握手可以简化为三次握手

 

三次握手标志位发生的变化

2.四次挥手断开连接

发送方发送断开连接,被接收方接收和应答,接收方会做一些断开前的准备工作.

一般来说FIN是由应用程序发起的,比如调用close()方法,所以是应用层面的,之后接收到发送方ACK应答,服务器就可以释放资源

为什么断开连接四次挥手不能转变为三次?

第一个ACK是操作系统(传输层)实现的TCP应答,第二个FIN是应用程序层面的,这两个操作是有时间差的,大概率是不会合并在一起的.

3.建立和断开连接

服务端状态转化:
  • [CLOSED -> LISTEN] 服务器端调用listen后进入LISTEN状态,等待客户端连接;
  • [LISTEN -> SYN_RCVD] 一旦监听到连接请求(同步报文段),就将该连接放入内核等待队列中,并向客户端发送SYN确认报文。
  • [SYN_RCVD -> ESTABLISHED] 服务端一旦收到客户端的确认报文,就进入ESTABLISHED态,可以进行读写数据了。
  • [ESTABLISHED -> CLOSE_WAIT] 当客户端主动关闭连接(调用close),服务器会收到结束 报文段,服务器返回确认报文段并进入CLOSE_WAIT
  • [CLOSE_WAIT -> LAST_ACK] 进入CLOSE_WAIT后说明服务器准备关闭连接(需要处理完之前的数据);当服务器真正调用close关闭连接时,会向客户端发送FIN,此时服务器进入
  • LAST_ACK状态,等待最后一个ACK到来(这个ACK是客户端确认收到了FIN
  • [LAST_ACK -> CLOSED] 服务器收到了对FINACK,彻底关闭连接。
客户端状态转化:
  • [CLOSED -> SYN_SENT] 客户端调用connect,发送同步报文段;
  • [SYN_SENT -> ESTABLISHED] connect调用成功,则进入ESTABLISHED状态,开始读写数 据;
  • [ESTABLISHED -> FIN_WAIT_1] 客户端主动调用close时,向服务器发送结束报文段,同时进FIN_WAIT_1
  • [FIN_WAIT_1 -> FIN_WAIT_2] 客户端收到服务器对结束报文段的确认,则进FIN_WAIT_2
  • 开始等待服务器的结束报文段;[FIN_WAIT_2 -> TIME_WAIT] 客户端收到服务器发来的结束报文段,进入TIME_WAIT,并发LAST_ACK
  • [TIME_WAIT -> CLOSED] 客户端要等待一个2MSLMax Segment Life,报文最大生存时 间)的时间,才会进入CLOSED状态。

四.滑动窗口(效率机制)

刚才我们讨论了确认应答策略,对每一个发送的数据段,都要给一个 ACK 确认应答.收到 ACK 后再发送下一个数据段.这样做有一个比较大的缺点,就是性能较差.尤其是数据往返的时间较长的时候.

 因此,我们设计了滑动窗口,一次发送特定数目的数据,可以大大提高效率.下面的案例窗口的大小为4,即一次可以发送四条SYN请求,当主机A接收到主机B发送的ACK应答的时候,滑动窗口向下进行移动,此时可以发送下一条的数据(4001--5000).

  • 窗口大小指的是无需等待确认应答而可以继续发送数据的最大值。上图的窗口大小就是4000个字节(四个段)。
  • 发送前四个段的时候,不需要等待任何ACK,直接发送;
  • 收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据;依次类推;
  • 操作系统内核为了维护这个滑动窗口,需要开辟 发送缓冲区 来记录当前还有哪些数据没有应答;只有确认应答过的数据,才能从缓冲区删掉;
  • 窗口越大,则网络的吞吐率就越高;
  • 假设窗口无限大,这个时候就效率就相当于UDP了.

那如果发生了丢包的问题,该如何解决呢?下面还是分两种情况进行考虑.

 情况一:数据包已经抵达,ACK被丢了。

这种情况下,部分ACK丢包了不要紧,可以根据后面的ACK进行确定.

比如确定序列为1001的ACK丢包了,但是后面2001的ACK应答被主机A成功接收了,我们可以根据这个应答确定前面的数据(1001)都已经接收了,因为如果没有接收到1--1000数据,序列号不会改变,就不会发送2001的ACK应答.

现实案例:别人问你学历,你说是初中,这说明你已经上过小学了.

考虑一下,如果最后一次ACK丢包,会发生什么情况?这个时候后面已经没有ACK应答了,因此这个时候我们只能触发超时重传完成最后一次的SYN和ACK应答.

 情况二:数据包就直接丢了。

  • 当某一段报文段丢失之后,发送端会一直收到 1001 这样的ACK,就像是在提醒发送端 "我想要的是 1001" 一样;
  • 如果发送端主机连续三次收到了同样一个 "1001" 这样的应答,就会将对应的数据 1001 -2000 重新发送;
  • 这个时候接收端收到了 1001 之后,再次返回的ACK就是7001了(因为2001 - 7000)接收端其实之前就已经收到了,被放到了接收端操作系统内核的接收缓冲区中;

这种机制被称为 "高速重发控制"(也叫 "快重传")。 

五.流量控制(效率机制)

主要是确定滑动窗口的大小,通过发送方与接收方动态协商来确认

每个程序在启动的时候都会去申请系统资源,发送和接收方缓冲区就是申请来的资源.

每次进行ACK应答的时候,ACK应答中将剩余空间的大小放在16位窗口大小,表示具体可以接收多少数据,通过接收方反制发送方对窗口大小的限制,发送方不能为了提高效率而无限的扩展窗口的大小.

 如果接收方的处理能力比较低,可能会出现缓冲区装满的情况,这个时候窗口的大小变为0,这个时候发送方不能再发送数据给接收.

 解决窗口大小问题

那么问题来了, 16 位数字最大表示 65535 ,那么 TCP 窗口最大就是 65535 字节么?
实际上, TCP 首部 40 字节选项中还包含了一个窗口扩大因子 M ,实际窗口大小是窗口字段的值左移 M 位;

六.拥塞控制(安全机制)

虽然TCP有了滑动窗口这个大杀器,能够高效可靠的发送大量的数据。但是如果在刚开始阶段就发送大量的数据,仍然可能引发问题。
因为网络上有很多的计算机,可能当前的网络状态就已经比较拥堵。在不清楚当前网络状态下,贸然发送大量的数据,是很有可能引起雪上加霜的。
TCP引入 慢启动 机制,先发少量的数据,探探路,摸清当前的网络拥堵状态,再决定按照多大的速度传输数据;

  1. 发送方第一次发送数据,窗口大小是1
  2. 接下来每一次发送数据,窗口大小以指数扩大2 4 8 16
  3. 当达到初始阈值时,不再以指数扩大,而是线性的方式增长,每次加1
  4. 当窗口达到或个值时,出现了大量的丢包现象,也就是说频繁的出现超时重传,就说明网络出现了堵塞
  5. 拥塞窗口的大小直接回到最小值1,新的拥塞窗口阈值也会被调整=当前拥塞窗口值/2
  6. 重复1-5步

具体窗口的大小以以下两个因素决定:①接收方缓存区的大小 ②拥塞控制中根据网络的状态确定下来的窗口大小       我们一般取两者的较小值作为实际窗口的大小

少量的丢包,我们仅仅是触发超时重传;大量的丢包,我们就认为网络拥塞;
当TCP通信开始后,网络吞吐量会逐渐上升;随着网络发生拥堵,吞吐量会立刻下降;

拥塞控制,归根结底是TCP协议想尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。

七.延迟应答(效率机制)

如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小

  • 假设接收端缓冲区为1M。一次收到了500K的数据;如果立刻应答,返回的窗口就是500K;但实际上可能处理端处理的速度很快,10ms之内就把500K数据从缓冲区消费掉了;
  • 在这种情况下,接收端处理还远没有达到自己的极限,即使窗口再放大一些,也能处理过来;
  • 如果接收端稍微等一会再应答,比如等待200ms再应答,那么这个时候返回的窗口大小就是1M;

可以选择以下两种情况来进行延迟应答:

  • 数量限制:每隔N个包就应答一次;
  • 时间限制:超过最大延迟时间就应答一次;

比如我们可以每两次请求,应答一次,比如第2,4,6应答.如果是偶数次请求,可以完成应答,如果是奇数次应答,那么最后一次就采用时间限制,超过一个系统默认的时间就应答.

八.捎带应答(效率机制)

由于延迟应答的存在,可能存在SYN报文和ACK报文同时发送的情况那么系统就会把两个报文合二为一(这就是三次握手建立连接可以把第一次ACK和第二次SYN合并在一起的原因)

九.面向字节流

1.粘包问题

在面向字节流中会出现的一个问题就是粘包问题

2.具体的现象

当发送方将数据发送给接受方的时候,发送的数据是以二进制(Java中的byte数组)进行传输的.接收方接受到之后,会存储到接收方的缓冲区中,发送方将多条数据发送给接收方,这多条数据一起存储到缓冲区中,此时如果我们不采取任何方式,多条数据存储到一块,这种不能有效区分消息边界的现象叫做粘包

 3.解决方案

如何解决粘包问题其实就是如何区分这些消息的边界.

1.在消息末尾加上特殊的分隔符来标识消息的结束

比如我们在每条消息的末尾加上\n来作为一条消息的结束.

你好啊,一会去吃火锅吧!!!\nHow are you.\n不回信息你是个猪吗?\n

在获取消息的时候我们可以使用特殊字符截取缓冲区的内容

2.使用一个专门用来描述消息体长度的字段,来标识消息体的具体长度

1.读取消息的时候,先把4byte的表示消息体长度的字段读取出来,比如第一个长度为:42

2.继续在缓冲区读取42个字节,这42个字节表示消息的内容

3.在读取4个byte的下一个消息的长度,重复上面操作.

举例:

JSON,用大括号来包裹消息,那么就可以理解为他是使用大括号做为特殊字符来表示消息结尾的HTTP,应用层的协议,既使用分隔符也使用了表示消息长度的字段解决粘包问题

十.TCP异常情况

1.程序崩溃 

操作系统是会感知到的,可以做相应的处理
操作系统会回收进程的资源,其中释放包括文件描述符表,就想当于调用了对应socket的close之后触发FIN操作,进而开始进入四次挥手,和普通的四次挥手没有区别.

2.正常关机

通过开始菜单或执行关机命令,系统会强制结所有进程,回收资源,与程序崩溃执行的流程类似

3.主机掉电操作

系统不会做出任何反应

  1. 接收方掉电
  • 发送方并不知道接收方挂了,继续发送数据·发送数据后收不到ACK应答,触发超时重传
  • 多次重传都没有收到ACK应答,会尝试进行连接重置(RST标识位)
  • 连接重置也失败,只能放弃连接
  1. 发送方掉电
  • 一般出现在长连接中,服务器与客户端会维护一个心跳包客户端每隔1秒给服务器发送一个数据包,证明自己存活)告诉对方我还在线,没有真实数据
  • 如果服务器一直收不到这个心跳包,比如过了10秒之后还没有收到,就判定为客户端挂了,自行断开连接
  • 客户端网络恢复之后再次进行重连即可

4.网线断开

与主机掉电的情况相同,只不过是主机都是正常工作的

十一.常见面试题

1.简述下三次握手,四次挥手的流程

上面已经讲解了,可以自行去看

2.为什么需要三次握手,两次不行吗?

上面已经讲解了,可以自行去看

3. UDP本身是无连接,不可靠,面向数据报的协议,如果要基于传输层UDP协议,来实现一个可靠传输,应该怎样设计?

4.UDP大小是受限的,如果要基于传输层UDP协议,传输超过64K的数据,应该如何设计?

问题三和问题四都可以基于TCP安全和效率机制进行回答,比如:

引入序列号,保证数据顺序;
引入确认应答,确保对端收到了数据;
引入超时重传,如果隔一段时间没有应答,就重发数据;

5.TCP和UDP的对比和区别.

TCP用于可靠传输的情况,应用于文件传输,重要状态更新等场景;
UDP用于对高速传输和实时性要求较高的通信领域,例如,早期的QQ,视频传输等。                 另外UDP可以用于广播;

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

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

相关文章

算法扩展第一次:收集雪花 【hash表,双指针,stl中的map】

算法详解 这道题需要新学的知识一个是双指针,一个是c库中的unordered_map容器 双指针 双指针原先我写过很多这方面的题,但是这道题我一开始是低估了它的难度,而且压根没有想到要用双指针,属于是长见识了,这道题的双…

Virtual box安装Ubuntu1804乱码

Virtual box安装Ubuntu1804乱码 1. 首先检查编码格式 运行以下命令打开locale配置文件: sudo nano /etc/default/locale2. 可能缺少字体,打开终端,先执行更新 sudo apt-get update 接着进入设置,搜索language,进入…

机器学习-搭建轻量级GPT2训练对话

在自己的机器上部署一个GPT简直太酷啦,因为模型数据缘故,所以这个机器人有时候傻傻的。。。 需要安装环境:python3.7 、Transformers4.2.0、pytorch1.7.0、nginx(映射网页文件) 我的系统:MAC m2 Mac默认是…

Jmeter如何安装jp@gc - Ultimate Thread Group插件(终极线程组)

首先明确一点,我们为什么要做压力测试? 压力测试是为了确保系统能够在负载高峰期和长时间运行的情况下保持高性能、稳定和可靠。同时也是软件开发生命周期中不可或缺的一环,帮助开发人员和系统管理员优化和调整系统,以提供卓越的…

2023春期末考试选择题R2-8计算最小生成树总权重详解

题目如图: 分析和计算: 题目给出一个图的邻接矩阵表示,要求求最小生成树的总开销。 根据Kruskal算法,根据邻接矩阵顶点连接情况,收集开销最小的边,直到所有顶点被收集,且无环路,即…

Debian 12 “bookworm“ 发布 - 通用操作系统

Debian 12 “bookworm” 发布 - 通用操作系统 基于 Linux kernel 6.1 LTS,支持 APFS 读写 请访问原文链接:https://sysin.org/blog/debian-12/,查看最新版。原创作品,转载请保留出处。 作者主页:sysin.org Debian 1…

(数组) 1365. 有多少小于当前数字的数字 ——【Leetcode每日一题】

❓1365. 有多少小于当前数字的数字 难度:简单 给你一个数组 nums,对于其中每个元素 nums[i],请你统计数组中比它小的所有数字的数目。 换而言之,对于每个 nums[i] 你必须计算出有效的 j 的数量,其中 j 满足 j ! i 且…

希捷科技:具有周期性价值的全球云存储之王

来源:猛兽财经 作者:猛兽财经 总结: (1)根据Statista的数据,希捷科技是全球硬盘驱动器市场的领导者,在全球拥有约43%的市场份额。 (2)希捷科技的管理层近期已经宣布了一…

Node.js模块化学习笔记

Node.js模块化 模块化雨模块 将一个复杂的程序文件依据一定规则(规范)拆分成多个文件的过程称之为模块化。 其中拆分的每个文件就是一个模块,模块的内部数据是私有的,不过模块可以暴露内部数据以便其他模块使用 模块化项目 编…

Python课期末考试复习

简答 定义函数的规则 1、函数代码块以def关键词开头,后接函数标识符名称和圆括号() 2、任何传入参数和自变量必须放在圆括号中间。圆括号之间可以用于定义参数。 3、函数的第一行语句可以选择性的使用文档字符串用于存放函数说明。 4、函数内容以冒号起始&#xf…

从前序与中序遍历序列构造二叉树

题目链接 从前序与中序遍历序列构造二叉树 题目描述 注意点 inorder.length preorder.lengthpreorder 和 inorder 均 无重复 元素inorder 均出现在 preorderpreorder 保证 为二叉树的前序遍历序列inorder 保证 为二叉树的中序遍历序列 解答思路 前序遍历的首个节点为根节…

[架构之路-211]- 需求- 软架构前的需求理解:ADMEMS标准化、有序化、结构化、层次化需求矩阵 =》需求框架

目录 前言: 一、什么是ADMES: 首先,需求是分层次的: 其次,需求是有结构的,有维度的 再次,不同层次需求、不同维度需求之间可以相互转化(难点、经验积累) 最终,标准…

UnitTest 学习

UnitTest 一、UnitTest 基本使用1. TestCase 测试用例2. TestSuite 和 TestRunner3. TestLoader 测试加载4. Fixture 二、断言与参数化断言参数化 三、测试报告获取项目的绝对路径登录案例跳过 一、UnitTest 基本使用 UnItTest 框架介绍 UnitTest是python自带的一个单元测试框…

HTTP 和 HTTPS 协议原理【网络基础】

文章目录 1. HTTP 的优点2. HTTP 的缺点明文可能会被窃听通信方可能被伪装报文可能被篡改 2.1 弥补 HTTP 的缺点(概述)加密明文通信加密内容加密 验证通信方报文完整性校验 3. HTTPS 协议3.1 SSL/TLS 协议概述3.2 加密机制对称加密非对称加密混合加密 3.…

一文终结SQL 子查询优化

概要 子查询(Subquery)的优化一直以来都是 SQL 查询优化中的难点之一。关联子查询的基本执行方式类似于 Nested-Loop,但是这种执行方式的效率常常低到难以忍受。当数据量稍大时,必须在优化器中对其进行去关联化(Decoor…

深入理解深度学习——Transformer:基础知识

分类目录:《深入理解深度学习》总目录 相关文章: 作为当下最先进的深度学习架构之一,Transformer被广泛应用于自然语言处理领域。它不单替代了以前流行的循环神经网络(recurrent neural network, RNN)和长短期记忆(long short-term memory, …

网络安全入门学习第十七课——PHP数组

文章目录 一、索引数组二、关联数组三、数组定义1、多维数组2、赋值方式3、短数组定义法([ ] PHP 5.4起增加的) 四、访问数组五、遍历数组1、使用 for 循环2、foreach语句遍历 六、合并两个数组1、“”联合运算符2、array_combine 函数 七、数组排序函数八、数组增删…

redis 全系列目录

redis常用资源_存在,及合理的博客-CSDN博客Redis 官网 推荐CRUG网站redis 中文 官网Spring Data Redis 客户端工具官网Distributed Locks with Redis | Redishttps://github.com/redisson/redisson 分布式锁实现大数据高并发Redis一本通-张文亮编著-微信读书 书籍推荐https://b…

Misc(三)

LSB 这题没见过,是看的wp 首先了解LSB是什么 LSB简介 最低有效位( least significant bit,LSB)指的是一个二进制数字中的最低位。最低有效位和最高有效位是相对应的概念。LSB是一种常被用做图片隐写的算法。LSB属于空域算法中的一…

学成在线----day6

1、断点续传 断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上…