TCP 协议(二)连接与断开

news2024/11/16 19:54:47

TCP 连接概述

TCP 协议是一种面向连接的、可靠的数据传输协议,同时 TCP 连接是全双工的,即连接的两端可以互传数据。在深入了解 TCP 连接之前,我们先来弄清楚整个 TCP 连接的过程,之后在深入整个数据报文结构来认识 TCP。

TCP连接

客户在传输数据报文之前会发送一个特殊的报文段,等待服务器返回一个特殊的报文段,在收到服务器返回的报文段后,客户再次向服务器端发送一个特殊报文段作为响应,这个过程其实就是 TCP 建立连接的过程,也称为“三次握手”阶段。需要注意的是,当客户再次发送特殊报文时是可以带上应用层数据的,而前两次的特殊报文段则不可以。

数据传输过程

一旦建立起来一条TCP连接,连个应用进程之间就可以相互传输应用数据了。这个过程:进程A通过套接字将数据流传递到运输层并在运输层进行封装成运输层的报文段,接下来由 TCP 控制将报文段放在 TCP 连接的发送缓存里,TCP 连接会不时地将报文段从发送缓存中取出来,为其加上 TCP 首部形成 TCP 报文段并传递到网络层中。而网络层则是将 TCP 报文段分别封装在IP 数据报里面并发送到网络中。当TCP 另一端接收到一个报文段后就会将其放在接收缓存中等待读取。

TCP 的连接与断开

在学习计算机网络之前,我们对于“三次握手”和“四次挥手”有所耳闻,其实这两个名词指的就是 TCP 连接过程与断开过程。在“三次握手”中TCP使用了两种特殊的报文段——SYN 报文段和 SYNACK 报文段,分别对应发送方的发起连接和接收方响应连接的过程报文;在“四次挥手”中,使用的是 FIN 比特置一的报文段和 ACK 报文段。
三次握手、四次挥手

11种状态名词解析​​​​​​​

LISTEN:等待从任何远端TCP 和端口的连接请求。
SYN_SENT:发送完一个连接请求后等待一个匹配的连接请求。
SYN_RECEIVED:发送连接请求并且接收到匹配的连接请求以后等待连接请求确认。
ESTABLISHED:表示一个打开的连接,接收到的数据可以被投递给用户。连接的数据传输阶段的正常状态。
FIN_WAIT_1:等待远端TCP 的连接终止请求,或者等待之前发送的连接终止请求的确认。
FIN_WAIT_2:等待远端TCP 的连接终止请求。
CLOSE_WAIT:等待本地用户的连接终止请求。
CLOSING:等待远端TCP 的连接终止请求确认。
LAST_ACK:等待先前发送给远端TCP 的连接终止请求的确认(包括它字节的连接终止请求的确认)
TIME_WAIT:等待足够的时间过去以确保远端TCP 接收到它的连接终止请求的确认。
	TIME_WAIT 两个存在的理由:
    1.可靠的实现tcp全双工连接的终止;
    2.允许老的重复分节在网络中消逝。
CLOSED:不在连接状态(这是为方便描述假想的状态,实际不存在)

三次握手

TCP 是面向连接的协议,所以使用 TCP 前必须先建立连接,而建立连接是通过三次握手而进行的。
三次握手

三次握手过程

1.一开始,客户端和服务端都处于 CLOSED 状态。先是服务端主动监听某个端口,处于 LISTEN 状态。
2.客户端会随机初始化序号(client_isn),将此序号置于 TCP 首部的「序号」字段中,同时把 SYN 标志位置为 1 ,表示 SYN 报文。接着把第一个 SYN 报文发送给服务端,表示向服务端发起连接,该报文不包含应用层数据,之后客户端处于 SYN_SENT 状态。
3.服务端收到客户端的 SYN 报文后,首先服务端也随机初始化自己的序号(server_isn),将此序号填入 TCP 首部的「序号」字段中,其次把 TCP 首部的「确认应答号」字段填入 client_isn + 1, 接着把 SYN 和 ACK 标志位置为 1。最后把该报文发给客户端,该报文也不包含应用层数据,之后服务端处于 SYN_RCVD 状态。
4.客户端收到服务端报文后,还要向服务端回应最后一个应答报文,首先该应答报文 TCP 首部 ACK 标志位置为 1 ,其次「确认应答号」字段填入 server_isn + 1 ,最后把报文发送给服务端,这次报文可以携带客户到服务器的数据,之后客户端处于 ESTABLISHED 状态。
5.服务器收到客户端的应答报文后,也进入 ESTABLISHED 状态。
从上面的过程可以发现第三次握手是可以携带数据的,前两次握手是不可以携带数据的。
一旦完成三次握手,双方都处于 ESTABLISHED 状态,此致连接就已建立完成,客户端和服务端就可以相互发送数据了。

如何在 Linux 系统中查看 TCP 状态?

TCP 的连接状态查看,在 Linux 可以通过 netstat -napt 命令查看。
netstat
Linux netstat 命令用于显示网络状态。
利用 netstat 指令可让你得知整个 Linux 系统的网络情况。
语法 netstat [-acCeFghilMnNoprstuvVwx][-A<网络类型>][–ip] 参数说明:

	-a,--–all 显示所有连线中的Socket。
	-A<网络类型>或–<网络类型> 列出该网络类型连线中的相关地址。
	-c,--continuous 持续列出网络状态。
	-C,--cache 显示路由器配置的快取信息。
	-e,--extend 显示网络其他相关信息。
	-F,--fib 显示FIB。
	-g,--groups 显示多重广播功能群组组员名单。
	-h,--help 在线帮助。
	-i,--interfaces 显示网络界面信息表单。
	-l,--listening 显示监控中的服务器的Socket。
	-M,--masquerade 显示伪装的网络连线。
	-n,--numeric 直接使用IP地址,而不通过域名服务器。
	-N,--netlink或–symbolic 显示网络硬件外围设备的符号连接名称。
	-o,--timers 显示计时器。
	-p,--programs 显示正在使用Socket的程序识别码和程序名称。
	-r,--route 显示Routing Table。
	-s,--statistics 显示网络工作信息统计表。
	-t,--tcp 显示TCP传输协议的连线状况。
	-u,--udp 显示UDP传输协议的连线状况。
	-v,--verbose 显示指令执行过程。
	-V,--version 显示版本信息。
	-w,--raw 显示RAW传输协议的连线状况。
	-x,--unix 此参数的效果和指定"-A unix"参数相同。
	--ip,--inet 此参数的效果和指定"-A inet"参数相同。

为什么是三次握手?不是两次、四次?

相信大家比较常回答的是:“因为三次握手才能保证双方具有接收和发送的能力”。
这回答是没问题,但这回答是片面的,并没有说出主要的原因。
在前面我们知道了什么是 TCP 连接:
用于保证可靠性和流量控制维护的某些状态信息,这些信息的组合,包括Socket、序列号和窗口大小称为连接。
所以,重要的是为什么三次握手才可以初始化Socket、序列号和窗口大小并建立 TCP 连接。
接下来以三个方面分析三次握手的原因:
三次握手才可以阻止重复历史连接的初始化(主要原因)
三次握手才可以同步双方的初始序列号
三次握手才可以避免资源浪费

原因一:阻止重复历史连接的初始化

简单来说,三次握手的首要原因是为了防止旧的重复连接初始化造成混乱。我们考虑一个场景,客户端先发送了 SYN(seq = 90) 报文,然后客户端宕机了,而且这个 SYN 报文还被网络阻塞了,服务端并没有收到,接着客户端重启后,又重新向服务端建立连接,发送了 SYN(seq = 100) 报文(注意!不是重传 SYN,重传的 SYN 的序列号是一样的)。
看看三次握手是如何阻止历史连接的:
三次握手避免历史链接
客户端连续发送多次 SYN (都是同一个四元组)建立连接的报文,在网络拥堵情况下:一个「旧 SYN 报文」比「最新的 SYN 」 报文早到达了服务端,那么此时服务端就会回一个 SYN + ACK 报文给客户端,此报文中的确认号是 91(90+1)。客户端收到后,发现自己期望收到的确认号应该是 100+1,而不是 90 + 1,于是就会回 RST(复位链接)报文。服务端收到 RST 报文后,就会释放连接。后续最新的 SYN 抵达了服务端后,客户端与服务端就可以正常的完成三次握手了。上述中的「旧 SYN 报文」称为历史连接,TCP 使用三次握手建立连接的最主要原因就是防止「历史连接」初始化了连接。

原因二:同步双方初始序列号

TCP 协议的通信双方, 都必须维护一个「序列号」, 序列号是可靠传输的一个关键因素,它的作用:
1).接收方可以去除重复的数据;
2).接收方可以根据数据包的序列号按序接收;
3).可以标识发送出去的数据包中, 哪些是已经被对方收到的;
可见,序列号在 TCP 连接中占据着非常重要的作用,所以当客户端发送携带「初始序列号」的 SYN 报文的时候,需要服务端回一个 ACK 应答报文,表示客户端的 SYN 报文已被服务端成功接收,那当服务端发送「初始序列号」给客户端的时候,依然也要得到客户端的应答回应,这样一来一回,才能确保双方的初始序列号能被可靠的同步。
同步双方初始序列号
四次握手其实也能够可靠的同步双方的初始化序号,但由于第二步和第三步可以优化成一步,所以就成了「三次握手」。
而两次握手只保证了一方的初始序列号能被对方成功接收,没办法保证双方的初始序列号都能被确认接收。

原因三:避免资源浪费

如果只有「两次握手」,当客户端的 SYN 请求连接在网络中阻塞,客户端没有接收到 ACK 报文,就会重新发送 SYN ,由于没有第三次握手,服务器不清楚客户端是否收到了自己发送的建立连接的 ACK 确认信号,所以每收到一个 SYN 就只能先主动建立一个连接,这会造成什么情况呢?
如果客户端的 SYN 阻塞了,重复发送多次 SYN 报文,那么服务器在收到请求后就会建立多个冗余的无效链接,造成不必要的资源浪费。
在这里插入图片描述
即两次握手会造成消息滞留情况下,服务器重复接受无用的连接请求 SYN 报文,而造成重复分配资源。

小结

TCP 建立连接时,通过三次握手能防止历史连接的建立,能减少双方不必要的资源开销,能帮助双方同步初始化序列号。序列号能够保证数据包不重复、不丢弃和按序传输。
不使用「两次握手」和「四次握手」的原因:
「两次握手」:无法防止历史连接的建立,会造成双方资源的浪费,也无法可靠的同步双方序列号;
「四次握手」:三次握手就已经理论上最少可靠连接建立,所以不需要使用更多的通信次数。

为什么客户端和服务端的初始序列号 ISN 是不相同的?

因为网络中的报文会延迟、会复制重发、也有可能丢失,这样会造成的不同连接之间产生互相影响,所以为了避免互相影响,客户端和服务端的初始序列号是随机且不同的。

初始序列号 ISN 是如何随机产生的?

起始 ISN 是基于时钟的,每 4 毫秒 + 1,转一圈要 4.55 个小时。
RFC1948 中提出了一个较好的初始化序列号 ISN 随机生成算法。
ISN = M + F (localhost, localport, remotehost, remoteport)
M 是一个计时器,这个计时器每隔 4 毫秒加 1。
F 是一个 Hash 算法,根据源 IP、目的 IP、源端口、目的端口生成一个随机数值。要保证 Hash 算法不能被外部轻易推算得出,用 MD5 算法是一个比较好的选择。

既然 IP 层会分片,为什么 TCP 层还需要 MSS 呢?

我们先来认识下 MTU 和 MSS
MTU
MTU:一个网络包的最大长度,以太网中一般为 1500 字节;
MSS:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度;
如果TCP 的整个报文(头部 + 数据)交给 IP 层进行分片,会有什么异常呢?
当 IP 层有一个超过 MTU 大小的数据(TCP 头部 + TCP 数据)要发送,那么 IP 层就要进行分片,把数据分片成若干片,保证每一个分片都小于 MTU。把一份 IP 数据报进行分片以后,由目标主机的 IP 层来进行重新组装后,在交给上一层 TCP 传输层。
这看起来井然有序,但这存在隐患的,那么当如果一个 IP 分片丢失,整个 IP 报文的所有分片都得重传。
因为 IP 层本身没有超时重传机制,它由传输层的 TCP 来负责超时和重传。
当接收方发现 TCP 报文(头部 + 数据)的某一片丢失后,则不会响应 ACK 给对方,那么发送方的 TCP 在超时后,就会重发「整个 TCP 报文(头部 + 数据)」。
因此,可以得知由 IP 层进行分片传输,是非常没有效率的。
所以,为了达到最佳的传输效能 TCP 协议在建立连接的时候通常要协商双方的 MSS 值,当 TCP 层发现数据超过 MSS 时,则就先会进行分片,当然由它形成的 IP 包的长度也就不会大于 MTU ,自然也就不用 IP 分片了。
MSS
经过 TCP 层分片后,如果一个 TCP 分片丢失后,进行重发时也是以 MSS 为单位,而不用重传所有的分片,大大增加了重传的效率。

什么是 SYN 攻击?如何避免 SYN 攻击?

SYN 攻击

我们都知道 TCP 连接建立是需要三次握手,假设攻击者短时间伪造不同 IP 地址的 SYN 报文,服务端每接收到一个 SYN 报文,就进入SYN_RCVD 状态,但服务端发送出去的 ACK + SYN 报文,无法得到未知 IP 主机的 ACK 应答,久而久之就会占满服务端的 SYN 接收队列(未连接队列),使得服务器不能为正常用户服务。
SYN 攻击

避免 SYN 攻击方式一

其中一种解决方式是通过修改 Linux 内核参数,控制队列大小和当队列满时应做什么处理。
当网卡接收数据包的速度大于内核处理的速度时,会有一个队列保存这些数据包。控制该队列的最大值如下参数:
net.core.netdev_max_backlog
SYN_RCVD 状态连接的最大个数:
net.ipv4.tcp_max_syn_backlog
超出处理能时,对新的 SYN 直接回 RST,丢弃连接:
net.ipv4.tcp_abort_on_overflow

避免 SYN 攻击方式二

我们先来看下Linux 内核的 SYN (未完成连接建立)队列与 Accpet (已完成连接建立)队列是如何工作的?
正常流程
正常流程:
当服务端接收到客户端的 SYN 报文时,会将其加入到内核的「 SYN 队列」;
接着发送 SYN + ACK 给客户端,等待客户端回应 ACK 报文;
服务端接收到 ACK 报文后,从「 SYN 队列」移除放入到「 Accept 队列」;
应用通过调用 accpet() socket 接口,从「 Accept 队列」取出的连接。
应用程序过慢
如果应用程序过慢时,就会导致「 Accept 队列」被占满。
SYN攻击二
如果不断受到 SYN 攻击,就会导致「 SYN 队列」被占满。
tcp_syncookies 的方式可以应对 SYN 攻击的方法:
net.ipv4.tcp_syncookies = 1
启动cookie
当「 SYN 队列」满之后,后续服务器收到 SYN 包,不进入「 SYN 队列」;
计算出一个 cookie 值,再以 SYN + ACK 中的「序列号」返回客户端,
服务端接收到客户端的应答报文时,服务器会检查这个 ACK 包的合法性。如果合法,直接放入到「 Accept 队列」。
最后应用通过调用 accpet() socket 接口,从「 Accept 队列」取出的连接。

四次挥手

四次挥手原理

第1次挥手:客户端发送一个 FIN,用来关闭客户端到服务端的数据传送,客户端进入 FIN_WAIT_1 状态;
第2次挥手:服务端收到 FIN 后,发送一个 ACK 给客户端,确认序号为收到序号+1(与 SYN 相同,一个 FIN 占用一个序号),服务端进入CLOSE_WAIT 状态;
第3次挥手:服务端发送一个 FIN,用来关闭服务端到客户端的数据传送,服务端进入 LAST_ACK 状态;
第4次挥手:客户端收到 FIN 后,客户端进入 TIME_WAIT 状态,接着发送一个 ACK 给 Server,确认序号为收到序号+1,服务端进入CLOSED 状态,完成四次挥手。
其中:FIN 标志位数置1,表示断开 TCP 连接。

四次挥手​​​​​​​过程详细说明:

1、客户端发送断开 TCP 连接请求的报文,将报文中的 FIN 字段置为1,表示需要断开 TCP 连接,其中报文中包含 seq 序列号,是由发送端随机生成的,(FIN=1,seq=x,x由客户端随机生成);
2、服务端会回复客户端发送的 TCP 断开请求报文,其包含seq序列号,是由回复端随机生成的,而且会产生ACK字段,ACK字段数值是在客户端发过来的seq序列号基础上加1进行回复,以便客户端收到信息时,知晓自己的TCP断开请求已经得到验证。(FIN=1,ACK=x+1,seq=y,y由服务端随机生成);
3、服务端在回复完客户端的TCP断开请求后,不会马上进行TCP连接的断开,服务端会先确保断开前,所有传输到A的数据是否已经传输完毕,一旦确认传输数据完毕,就会将回复报文的 FIN 字段置1,并且产生随机seq序列号。(FIN=1,ACK=x+1,seq=z,z由服务端随机生成);
4、客户端收到服务端的 TCP 断开请求后,会回复服务端的断开请求,包含随机生成的seq字段和ACK字段,ACK字段会在服务端的TCP断开请求的seq基础上加1,从而完成服务端请求的验证回复。(FIN=1,ACK=z+1,seq=h,h为客户端随机生成)
至此TCP断开的4次挥手过程完毕。

TCP 的状态转换

TCP 相关

参考:
https://blog.csdn.net/qq_32907195/article/details/108335868
https://blog.csdn.net/m0_38106923/article/details/108292454

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

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

相关文章

全网最全,adb常用命令大全(详细)全覆盖,看这篇就够了..

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 adb 模拟按键输入…

python subprocess执行外部命令常用方法

subprocess模块是Python标准库中的一个模块&#xff0c;用于创建和控制子进程。它提供了一种在Python程序中调用其他外部命令、执行系统命令和与系统进程进行交互的方法。常用的有两种方法&#xff1a;subprocess.run()&#xff0c;subprocess.Popen() 1. subprocess.run()方法…

回顾类与对象:掌握String探索其模拟实现的沉浸式体验

目录 一.STL简介二.string的模拟实现1.成员变量与(拷贝)构造、析构函数2.运算符重载[ ]3.添加数据与扩容4.赋值运算符重载及其他重载5.其他函数 一.STL简介 标准模板库 STL是C标准库的重要组成部分&#xff0c;stl分为六大组件&#xff1a;算法、容器、迭代器、空间适配器、仿…

NLP实战7:seq2seq翻译实战-Pytorch复现

&#x1f368; 本文为[&#x1f517;365天深度学习训练营]内部限免文章&#xff08;版权归 *K同学啊* 所有&#xff09; &#x1f356; 作者&#xff1a;[K同学啊] &#x1f4cc; 本周任务&#xff1a; ●请根据N5、N6周内容&#xff0c;为解码器添加上注意力机制 一、前期准备…

常用分类损失CE Loss、Focal Loss及GHMC Loss理解与总结

一、CE Loss 定义 交叉熵损失&#xff08;Cross-Entropy Loss&#xff0c;CE Loss&#xff09;能够衡量同一个随机变量中的两个不同概率分布的差异程度&#xff0c;当两个概率分布越接近时&#xff0c;交叉熵损失越小&#xff0c;表示模型预测结果越准确。 公式 二分类 二…

【QT】QT搭建OpenCV环境

QT/OpenCV 01、开始之前02、QT03、CMake04、OpenCV05、配置06、测试 01、开始之前 本文版本&#xff1a; 1、QT&#xff1a;Based on Qt 5.12.2 (MSVC 2017, 32 bit)&#xff0c;编译方式是MinGW 2、CMake&#xff1a;cmake-3.27.0-rc4-windows-x86_64.msi 3、OpenCV&#xff1…

2023年值得入手的开放式耳机推荐,蓝牙耳机的选购指南分享推荐

身为一个音乐爱好者&#xff0c;出于对音质和佩戴舒适的追求&#xff0c;也有入手了很多品类的耳机&#xff0c;其中不乏有有线耳机、无线蓝牙耳机&#xff0c;两种不同的音频传输方式大类&#xff0c;其各自所拥有的特性也是不同的。而居于后者的无线蓝牙耳机&#xff0c;在现…

【Java基础教程】(八)面向对象篇 · 第二讲:Java 数组全面解析——动态与静态初始化、二维数组、方法参数传递、排序与转置、对象数组、操作API~

Java基础教程之面向对象 第二讲 本节学习目标1️⃣ 概念1.1 动态初始化1.2 静态初始化 2️⃣ 二维数组3️⃣ 数组与方法参数的传递4️⃣ 数组排序5️⃣ 数组转置6️⃣ 对象数组7️⃣ 数组操作API7.1 数组复制7.2 数组排序 &#x1f33e; 总结 本节学习目标 掌握数组的动态及静…

水库监测中仪器安装及监测结果的要求有哪些

水库监测点位布设需要根据水库运行情况和安全监测的需求来进行&#xff0c;一般分为基础监测点位和重要部位监测点位&#xff0c;基础监测点位主要包括上游水位、上游库水位变幅、库岸稳定以及上下游坝坡稳定等。重要部位监测点位主要包括坝轴线、溢洪道进口和泄水洞出口等部位…

前端报错:“Uncaught SyntaxError: missing ) after argument list“只是参数列表后面缺少 “)”?

报错"Uncaught SyntaxError: missing ) after argument list"&#xff0c;字面翻译过来的意思&#xff1a;语法错误: 参数列表后面缺少 )。 一直以为是少了 一个小括号找了好久 发现并不是 据提示是参数列表的问题&#xff0c;找到文件中存在参数列表的地方。如下图…

如何利用MyBatis完成web项目的环境搭建(导入核心依赖包、日志、编译环境,配置文件以及Druid连接池)

目录 项目环境搭建 servlet实例 核心依赖 导入日志 编译环境 mapper注册 resouces中 dao中 MyBatis配置文件 实例效果 导入配置文件 Druid连接池 Druid连接池是什么&#xff1f; 如何配置Druid连接池&#xff1f; 实体类 实例效果 项目环境搭建 1.在pom.xml中…

STM32 Proteus UCOSII系统锅炉报警系统设计压力温度水位-0059

STM32 Proteus UCOSII系统锅炉报警系统设计压力温度水位-0059 Proteus仿真小实验&#xff1a; STM32 Proteus UCOSII系统锅炉报警系统设计压力温度水位-0059 功能&#xff1a; 硬件组成&#xff1a;51单片机 8位数码管MAX7219数码管驱动模块多个按键LED灯蜂鸣器 1.准确测量…

IronOCR for .NET 2023.7.0 Crack

IronOCR for .NET 关于 读取 .NET 应用程序中图像和 Pdf 文本的高级 OCR &#xff08;光学字符识别&#xff09; 库。 IronOCR for .NET enables software engineers to read text content from images & PDFs in .NET applications and Web sites. Read text and barcod…

HarmonyOS/OpenHarmony应用开发-程序包安装、卸载、更新流程

一、应用程序包安装和卸载流程 1.开发者 开发者可以通过调试命令进行应用的安装和卸载&#xff0c;可参考多HAP的调试流程。 图1 应用程序包安装和卸载流程&#xff08;开发者&#xff09; 2.终端设备用户 开发者将应用上架应用市场后&#xff0c;终端设备用户可以在终端设…

python_day4_dict

字典dict:键值对(无重复,无下标索引&#xff09; my_dict {python: 99, java: 88, c: 77, c: 66} my_dict2 {} # 空字典 my_dict3 dict() print(f"my_dict:{my_dict},类型为&#xff1a;{type(my_dict)}") print(f"my_dict2:{my_dict2},类型为&#xff1a;…

AI应用系列--- TalkingPhoto 会说话的照片

利用HeyGen的服务可以生成有趣的Talkingphoto&#xff0c;方法有二&#xff1a; 1、访问HeyGen - AI Video Generator 网站&#xff0c;登录后即可根据提示或者案例生成talkingphoto 2、是使用HeyGen的 Discord​​​​​​机器人&#xff1a;https://discord.com/channels/1…

MySQL数据库期末项目 图书馆管理系统

1 项目需求分析 1.1 项目名称 图书馆管理系统 1.2 项目功能 在以前大多部分图书馆都是由人工直接管理&#xff0c;其中每天的业务和操作流程非常繁琐复杂&#xff0c;纸质版的登记信息耗费了大量的人力物力。因此图书馆管理系统应运而生&#xff0c;该系统采用智能化设计&#…

我来为你揭秘如何将音频转文字才简单

曾经有一位聋哑人士&#xff0c;他很想写一本回忆录&#xff0c;但是因为无法听取自己的回忆录音&#xff0c;他不得不寻找其他方法。于是&#xff0c;他试着用一些软件将他的录音转成文字&#xff0c;但是结果却非常糟糕&#xff0c;充斥着大量错误和不连贯的词语。于是&#…

【大虾送书第一期】《高并发架构实战:从需求分析到系统设计》

目录 ✨写在前面 ✨足够真实的高并发系统设计场景 ✨贴合工作场景的设计文档形式 ✨求同存异的典型系统架构案例 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &#x1f990;专栏地址&#xff1a;免费送书活动专栏地址 写在前面 很多软件工程师的职业规划是成为架构师&a…

手机副业哪些靠谱,推荐几个兼职思路

科思创业汇 大家好&#xff0c;这里是科思创业汇&#xff0c;一个轻资产创业孵化平台。赚钱的方式有很多种&#xff0c;我希望在科思创业汇能够给你带来最快乐的那一种&#xff01; 下面给大家介绍几个靠谱的兼职项目 1.问答答主 知乎、百度、悟空等渠道做问答&#xff0c;…