Linux网络编程 深入解析Linux TCP:TCP实操,三次握手和四次挥手的底层分析
知识点1【TCP编程概述】
1、TCP的概述
客户端:主动连接服务器,和服务器进行通信
服务器:被动被客户端连接,启动新的线程或进程,服务器客户端(并发服务器)
这里重复TCP和UDP特点
TCP(传输控制协议):是一种靠谱的传输层协议,
买电话 买电话卡 开声音 按下接听
知识点2【TCP客户端编程】
1、创建TCP套接字
SOCK_STREAM
socket函数创建的TCP套接字,没有端口,且默认是主动连接特性
2、connect函数连接服务器
#include <sys/types.h> #include <sys/socket.h>int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
功能介绍
客户端主动发出与TCP服务器的连接(三次握手)
参数
sockfd:客户端套接字
addr:只想服务器的地址结构体
addrlen:地址结构体的长度
返回值
成功:0
失败:返回-1
注意
TCP客户端通信之前,必须实现 建立和服务器之间的连接
connect连接成功一个服务器,不能再次连接其他服务器
inet_addr()(补充函数,平替pton)函数仅支持IPv4
如果socket没有固定端口,在调用connect时系统自动分配随机端口为源端口
connect实际上是带阻塞的,需要三次握手
3、send发送消息
#include <sys/types.h>
#include <sys/socket.h>
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
功能介绍
通过已连接套接字发送数据
参数
sockfd:已连接套接字(下面accept函数中会介绍)
buf:带发送数据的缓冲区指针
len:要发送的字节数
flags:控制标志
MSG_OOB
:发送带外数据(紧急数据)。MSG_DONTWAIT
:非阻塞发送(立即返回)。MSG_NOSIGNAL
:禁止发送SIGPIPE
信号。
返回值
成功:返回实际发送的字节数
失败:返回-1
注意
TCP不能发出0长度报文,但是UDP可以。
4、recv接收数据(默认阻塞)
#include <sys/types.h>#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);
功能介绍
从已连接套接字接收数据
参数
sockfd:已连接套接字
buf:接收数据的缓冲区指针
len:缓冲区最大容量
falgs:控制标记
返回值
成功:返回实际接收到的字节数
失败:返回-1
注意
recv如果收到0长度报文,表明对方已经断开连接,因此我们使用send的时候,不能发送0长度报文
只要一方关闭,另外一方就会收到0长度报文
知识点3【TCP服务器编程】
我们先把服务器的过程形象化:
1、socket() 买手机
2、bind() 买电话卡
3、listen() 打开声音
4、accept() 接听
1、作为服务器的条件
1、需要为服务器绑定一个固定的端口、IP(连接作用)
2、让操作系统知道这是一个服务器,而不是客户端
(使用listen函数让服务器具备监听功能,使套接字由主动变被动)
3、等待客户端的连接到来,使用accept提取到来的客户端
2、listen监听函数
#include <sys/types.h> /* See NOTES */#include <sys/socket.h>int listen(int sockfd, int backlog);
功能介绍
将套接字设为被动监听模式,等待客户端连接
参数
sockfd:套接字
backlog:连接队列的最大长度
返回值
成功:0
失败:-1
函数功能详解(底层)
1、将sockfd由主动变被动,并且对sockfd进行监听客户端连接的到来
2、backlog是连接队列的大小,表示客户端的最大个数
连接队列大小分析:
1、在listen后,在TCP服务器中,套接字改称为监听套接字,所有客户端想要连接,就需要向这个客户端发送连接请求
2、客户端发出连接请求(connect),TCP的server就会创建一个连接队列
3、连接队列又会分为两部分,但是总大小是上面对应的个数
(1)完成连接——三次握手之后
(2)未完成连接——三次握手完成之前
图形解析
这里说一个早期的一个攻击手段:SYN洪流攻击
就是一直发送低于三次握手信号(半成品),这样的信号全部在连接队列的未完成连接中存储,服务器也无法处理,当达到连接队列的最大值后,正常连接反而进不去连接队列。
这里
我们写监听函数,并阻塞,查看其网络状态
netstate -anp | grep a.out
可以看到此时处于监听状态(想系统说明此时是一个服务器)
3、accept提取客户端的连接(阻塞)
#include <sys/socket.h>int accept(int socket, struct sockaddr *restrict address,socklen_t *restrict address_len);
函数功能
accept只能从 连接队列 中 处于 完成连接部分 中提取连接
将提取到的该客户端的信息存到addr中
将提取到的该客户端从连接队列中删除
参数
sockfd:监听套接字
addr:存放的是 客户端 的地址信息
addrlen:地址结构体的长度的地址
返回值
成功:返回一个已连接套接字,这个套接字才代表服务器和该客户端的连接端点(真正和客户端的连接)
解释:如果服务器想要和该客户端通信,就需要向这个 已连接套接字 中读写
失败:返回-1
注意
调用一次,只能提取一个客户端对应的连接,如果连接队列没有客户端连接,将阻塞
因为是从 连接队列 中提取的原因,遵循先进先出的原则
验证一下:通过两个客户端,都连接我们写的服务器,会发现只有一个能发送
TCP服务器代码演示
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>int main(int argc, char const *argv[])
{//创建监听套接字int fd_sock_lis = socket(AF_INET,SOCK_STREAM,0);if(fd_sock_lis < 0){perror("socket_lis");_exit(-1);}//绑定固定端口 这里我们设置为8000struct sockaddr_in addr_bind;bzero(&addr_bind,sizeof(addr_bind));addr_bind.sin_family = AF_INET;addr_bind.sin_port = htons(8000);addr_bind.sin_addr.s_addr = htonl(INADDR_ANY);int ret_bind = bind(fd_sock_lis,(struct sockaddr *)&addr_bind,sizeof(addr_bind));if(ret_bind < 0){perror("bind");_exit(-1);}//监听 参数:监听套接字,连接队列的个数int ret_listen = listen(fd_sock_lis,10);if(ret_listen == -1){perror("listen");_exit(-1);} //提取客户端连接,已连接套接字的创建,已连接套接字理解为通信端口的一端//服务器通过操作这个已连接套接字与客户端进行联系struct sockaddr_in addr_accept;bzero(&addr_accept,sizeof(addr_accept));int len_accept = sizeof(addr_accept);int fd_sock_connect = accept(fd_sock_lis,(struct sockaddr *)&addr_accept,&len_accept);if(fd_sock_connect < 0){perror("accept");_exit(-1); }//接收数据,从已连接套接字中接收char arr_recv[256] = "";recv(fd_sock_connect,arr_recv,sizeof(arr_recv),0);//处理 客户端端口 的信息int port_client = ntohs(addr_accept.sin_port);char ip_client[16] = "";inet_ntop(AF_INET,&addr_accept.sin_addr.s_addr,ip_client,sizeof(ip_client));//遍历接收到的信息printf("从IP:%s的%d端口,获取的数据是%s\\n",ip_client,port_client,arr_recv);//发送应答send(fd_sock_connect,"ok",sizeof("ok"),0);//关闭 所有套接字close(fd_sock_connect);close(fd_sock_lis);return 0;
}
代码运行结果
知识点4【close关闭套接字】
当客户端用完后会调用close套接字,服务器也要关闭套接字(监听套接字,已连接套接字)
1、作为客户端
close(套接字),断开当前的连接,导致服务器收到0长度报文
2、作为服务器
close(监听套接字),该服务器不能监听新的连接的到来,但是不影响已连接客户端的通信
close(已连接套接字),只是断开当前客户端的连接,不会影响监听套接字(服务器可以继续监听新的连接的到来)
这里我们形象化一下
形象化理解
媒婆 监听套接字
小帅 客户端套接字
小美 已连接套接字
小帅找媒婆介绍对象,媒婆有个名单,把小美介绍给了小帅,小美和小帅分还是合,最后不会影响媒婆招揽其他生意
如果媒婆不想干媒婆这一行了,去转学嵌入式了,也不会影响小帅和小美的关系
3、下面内容前提
握手,挥手都涉及到底层,我们需要用抓包的操作来了解这一过程,我这里用的抓包工具是 wireshark
这是 我使用的抓包工具获取的上面的发送过程
由于我的 图不太好识别
我用我老师当时的抓包图片(很标准的三次握手,数据通信,四次挥手抓包过程)
我们分为三个流程 1、三次握手,2、数据通信,3、四次挥手 这里大家先看一下总的流程图,流程图是当时老师画的,我感觉很牛,这里直接使用了
知识点4【三次握手】(重要 背!!)
当客户端调用connect连接服务器,底层会完成三次握手信号,此时客户端阻塞,当三次握手信号完成,connect才会解除阻塞往下执行
三次握手的发起者 是客户端
1、TCP的头部
这里先介绍一下 TCP的头部
1、SYN:置1,表示报文是 连接请求报文
2、FIN:置1,表示报文是 关闭请求报文
3、ACK:置1,表示报文是 回应(应答)报文
4、URG:置1,表明紧急指针字段有效,告诉操作系统此报文内有紧急数据,请尽快传送
5、PUSH:置1:推送报文
6、RST:置1:复位连接
注意
序列号:seq,当前报文的编号。
确认序号:当前报文希望接下来对方发送的报文编号
ack(确认序号)数据分析
1、当无数据时,ack = 对方原编号 + 1
2、当 有数据时,ack = 对房源编号 + 接收到数据长度
2、三次握手
分析过程
1、当客户端调用connect后,底层发送SYN连接请求
此时seq = 0,ack = 0
2、服务器收到客户端发出的SYN请求,服务器给客户端回应SYN和ACK应答
此时seq = 1,ack = 1(无数据)
3、客户端接收到服务器发送的SYN请求后,向服务器发送ACK应答
此时seq = 1,ack = 1(原本服务器seq = 0,无数据+1后为1)
形象化理解
小帅给小美表白
小帅:我喜欢你(SYN)
小美:我知道(ACK),我也喜欢你(SYN)
小帅:其实我也知道(ACK)
3、分析通信过程
这里客户端发送的时”hello ack“,服务器应答我们设置的时”ok”
现在我们分析一下(每个红线是一个步骤)
分析过程
1、客户端和服务器经过三次握手后已经 完成连接(连接列表),客户端向服务器发送”hello ack“
这里有一个技巧:连续的线都是一个方向时,线对应的seq和ack是一样的
此时seq = 1,ack = 1,len = 9
2、服务器收到数据后,及其长度,发出ACK应答
此时seq = 1(与上面的ack相对应),ack = 10( 1+len(9))
3、服务器发送数据“ok”后,客户端接收
此时seq = 1,ack = 10(线 连续且方向一样),len = 2
4、客户端接收数据,发出ACK应答
此时seq = 10,ack = 3
确认序号的作用
1、当发送端数据时500位的时候,接收时仅收到了256位
此时len = 500,但实际发送的时候 接受到的长度的时256
这时,ack的值位 对方原序号码 + 256
接收端收到后,用ack - 原序号吗算出 接收数据长度,发现与发送数据长度不同,底层会处理后,继续发送没有接收的数据。
2、检验是否发生错误传输,这里不多介绍
4、四次挥手
这里补充一个概念:FIN标志位置1的前提是调用close函数
服务器和客户端都可以先退出,一般都是客户端先退出
分析过程
1、当客户端调用close(套接字)函数,触发底层发出FIN断开连接的请求。
2、服务器收到FIN关闭请求,做出ACK应答(服务器进入CLOSE_WAIT状态)。
CLOSE_WAIT状态是指对方套接字已经关闭,等待 服务器 已连接套接字关闭,即调用close(对应已连接套接字)
3、服务器应用层调用close函数后,触发底层发送FIN。
4、客户端收到FIN请求,回应ACK。
以上内容依次是四次挥手
下面我想补充说明一些知识点
补充(重要)
1、细心的同学已经发现了,在第三次回收后,客户端的状态时TIME_WAIT,它在等上面?
第四次回收 涉及到服务器到CLOSE的关闭状态的转换,因此需要保证其正确执行
TIME_WAIT等待是有时间时间限制的,在规定时间内,发现服务器没有重发FIN(即二次挥手),就意味着,ACK(第四次挥手)已经成功被服务器收到,客户端也会变为CLOSE状态。
如果在规定时间内,客户端又收到了(第三次挥手),表明出现了问题,此时客户端会再次四次挥手,然后重复等待。
2、补充问题(技术面常问问题 )
(1)为什么要四次挥手,而不能向三次握手一样,在第二次握手中一起将ACK和SYN一起发送给客户端?
因为第三次挥手的触发条件是,等待服务器调用close(已连接套接字),有一个等待的过程,因此不能和ACK一起发送。
(2)客户端都已经调用了close为什么还能执行 四次挥手的操作?
因为close只是关闭客户端中的套接字,此时是半关闭状态,仅关闭这个套接字应用层的数据的收发,而将FIN,ACK这些标志位置1的操作,是在底层实现的,并不是close负责的,因此可以执行四次挥手的操作。
5、状态转换
在图中大家可以看到有很多状态,下面介绍一下这些状态都是什么
下面是状态转换流程图
介绍
红色是服务器的状态转换图,蓝色是客户端的状态转换图
结束
代码重在练习!
代码重在练习!
代码重在练习!
今天的分享就到此结束了,希望对你有所帮助,如果你喜欢我的分享,请点赞收藏夹关注,谢谢大家!!!
相关文章:
Linux网络编程 深入解析Linux TCP:TCP实操,三次握手和四次挥手的底层分析
知识点1【TCP编程概述】 1、TCP的概述 客户端:主动连接服务器,和服务器进行通信 服务器:被动被客户端连接,启动新的线程或进程,服务器客户端(并发服务器) 这里重复TCP和UDP特点 TCP&#x…...
实验4基于神经网络的模式识别实验
实验原理 1. BP学习算法是通过反向学习过程使误差最小,其算法过程从输出节点开始,反向地向第一隐含层(即最接近输入层的隐含层)传播由总误差引起的权值修正。BP网络不仅含有输入节点和输出节点,而且含有一层或多层隐(层)节点。输入信号先向前…...
Rust网络编程实战:全面掌握reqwest库的高级用法
一、开篇导引 1.1 对比Python Requests解释为何reqwest是Rust生态的标杆HTTP客户端 在Python生态中,Requests 库以其简洁易用的API成为了HTTP客户端的首选。它使得开发者能够轻松地发送各种HTTP请求,处理响应,而无需过多关注底层细节。然而…...
【漫话机器学习系列】211.驻点(Stationary Points)
驻点(Stationary Points):理解函数导数为零的关键位置 在数学分析、机器学习优化、物理建模等领域中,驻点(Stationary Points)是一个非常重要的概念。它们是函数图像中“停下来的点”,即导数为…...
图 - 最小生成树算法 - Kruskal - Prim
目录 前言 什么是最小生成树算法 Kruskal 克鲁斯卡尔 Prim 普利姆 结语 前言 在图中一共有两类算法,一种是最短路径,还有一种就是本篇要讲解的最小生成树算法了 其中,最短路径一共有三种,而最小生成树一共有两种ÿ…...
linux kernel irq相关函数详解
在Linux内核驱动开发中,处理中断涉及一系列关键函数,正确使用这些函数对确保驱动的稳定性和性能至关重要。以下是disable_irq、free_irq、platform_get_irq和request_irq等函数的详细解析,涵盖其功能、用法、注意事项及示例代码。 一、核心函…...
聊聊Doris的数据模型,如何用结构化设计解决实时分析难题
传统 OLAP 系统的局限 在大数据实时分析领域,数据模型设计直接决定了系统的查询性能、存储效率与业务适配性。Apache Doris作为新一代MPP分析型数据库,通过独创的多模型融合架构,在业内率先实现了"一份数据支持多种分析范式"的能力…...
[Swift]Xcode模拟器无法请求http接口问题
1.以前偷懒一直是这样设置 <key>NSAppTransportSecurity</key> <dict><key>NSAllowsArbitraryLoads</key><true/> </dict> 现在我在Xcode16.3上,这种设置方式在真机上能请求http(应该是设备开启了开发者模式…...
kafka认证部署
首先启动 zookeeper /home/kafka/bin/zookeeper-server-start.sh /home/kafka/config/zookeeper.properties 创建SCRAM证书 /home/kafka/bin/kafka-configs.sh --zookeeper localhost:2181 --alter --add-config SCRAM-SHA-256[iterations8192,passwordliebe],SCRAM-SHA-512[p…...
基于STM32中断讲解
基于STM32中断讲解 一、NVIC讲解 简介:当一个中断请求到达时,NVIC会确定其优先级并决定是否应该中断当前执行的程序,以便及时响应和处理该中断请求。这种设计有助于提高系统的响应速度和可靠性,特别是在需要处理大量中断请求的实…...
Java 动态代理教程(JDK 动态代理)(以RPC 过程为例)
1. 什么是动态代理 在运行时为指定的接口自动生成代理对象,并通过 invoke 方法增强了这些对象的功能 2. 两个核心组件 java.lang.reflect.Proxy类 这个类提供了方法:newProxyInstance()用来创建一个代理对象 public static Object newProxyInstance(…...
Linux Privilege Escalation: LD_PRELOAD
声明:本文所有操作需在授权环境下进行,严禁非法使用! 0x01 什么是 LD_PRELOAD? LD_PRELOAD 是 Linux 系统中一个特殊的环境变量,它允许用户在程序启动时优先加载自定义的动态链接库(.so 文件)&…...
Java 并发性能优化:线程池的最佳实践
Java 并发性能优化:线程池的最佳实践 在 Java 并发编程的世界里,线程池堪称提高应用性能与稳定性的神器。恰如其分地运用线程池,能让我们在多线程任务调度时游刃有余,既能避免线程频繁创建销毁带来的开销,又能合理管控…...
QML动画--ParallelAnimation和SequentialAnimation
一、ParallelAnimation ParallelAnimation 是 QML 中用于并行执行多个动画的容器动画类型,可以同时运行多个子动画。 基本用法 qml import QtQuick 2.15Rectangle {id: rectwidth: 100; height: 100color: "red"x: 0; y: 0; opacity: 1.0ParallelAnim…...
深入解析进程与线程:区别、联系及Java实现
引言 在现代操作系统中,进程和线程是并发编程的两大核心概念。理解它们的区别与联系对开发高性能、高可靠性的程序至关重要。本文将通过原理分析和Java代码示例,深入探讨这两个关键概念。 一、基本概念 1.1 进程(Process) 定义&…...
c++:线程(std::thread)
目录 从第一性原理出发:为什么需要线程? ✅ 本质定义: 📌 使用基本语法: 线程之间的“并发”与“并行”的区别 线程安全与数据竞争(Race Condition) 如何让线程“安全地”访问数据&#x…...
基于LSTM-AutoEncoder的心电信号时间序列数据异常检测(PyTorch版)
心电信号(ECG)的异常检测对心血管疾病早期预警至关重要,但传统方法面临时序依赖建模不足与噪声敏感等问题。本文使用一种基于LSTM-AutoEncoder的深度时序异常检测框架,通过编码器-解码器结构捕捉心电信号的长期时空依赖特征&#…...
[密码学基础]GM/T 0018-2023 密码设备应用接口规范深度解析:技术革新与开发者实践
GM/T 0018-2023 密码设备应用接口规范深度解析:技术革新与开发者实践 GM/T 0018-2023《密码设备应用接口规范》是中国密码行业的重要标准,于2023年12月4日发布,2024年6月1日正式实施,替代了2012年版标准。该标准旨在规范密码设备…...
深入理解 Java 多线程:锁策略与线程安全
文章目录 一、常见的锁策略1. 乐观锁&&悲观锁2. 读写锁3. 重量级锁&&轻量级锁4. 自旋锁5. 公平锁&&不公平锁6. 可重入锁 && 不可重入锁 二、CAS1. 什么是 CAS2. CAS 是怎么实现的3.CAS 有哪些应用1) 实现原子类2) 实现自旋锁 4. CAS 的 ABA 问…...
Java从入门到“放弃”(精通)之旅——数组的定义与使用⑥
Java从入门到“放弃”(精通)之旅🚀——数组⑥ 前言——什么是数组? 数组:可以看成是相同类型元素的一个集合,在内存中是一段连续的空间。比如现实中的车库,在java中,包含6个整形类…...
VsCode搭建
安全性问题的声明: VScode是一个由微软出品的开源软件编辑器 VScode下载 https://code.visualstudio.com/Download 官网直接下载即可,windows和linux的vscode使用命令是类似的。 VScode插件相关 为了方便安装,推荐设置并使用vscode插件的…...
【NLP 65、实践 ⑯ 基于Agent优化文章】
羁绊由我而起,痛苦也由我承担 —— 25.4.18 一、⭐【核心函数】定义大模型调用函数 call_large_model prompt:用户传入的提示词(如 “请分析这篇作文的主题”),指导模型执行任务 client:Zhipu…...
【Redis】从单机架构到分布式,回溯架构的成长设计美学
前言 🌟🌟本期讲解关于分布式架构的发展相关知识介绍~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 🎆那么废…...
增量式PID基础解析与代码实例:温控系统
目录 1. 前言 2. 增量式PID控制的基本原理 2.1 PID控制的基本概念 2.2 增量式PID控制的特点 3. 增量式PID控制的Python实现:温控系统 3.1 构建增量式PID控制器 3.2 使用增量式PID控制器 3.3 运行模拟 3.4 完整代码 4. 参数调整与优化 4.1 参数选择 4.2…...
数据结构——栈以及相应的操作
栈(Stack) 在维基百科中是这样定义的: 堆栈(stack) 又称为栈或堆叠,是计算机科学中的一种抽象资料类型,只允许在有序的线性资料集合中的一端(称为堆栈顶端,top)进行加入数据(push)和…...
opencv 图像的旋转
图像的旋转 1 单点旋转2. 图片旋转(cv2.getRotationMatrix2D)3. 插值方法3.1 最近邻插值(cv2.INTER_NEAREST)3.2 双线性插值(cv2.INTER_LINEAR)3.3 像素区域插值(cv2.INTER_AREA)3.4 双三次插值(cv2.INTER_CUBIC&#…...
P3916 图的遍历
P3916 图的遍历 题目来源-洛谷 题意 有向图中,找出每个节点能访问到的最大的节点 思路 每个节点的最大节点,不是最长距离,如果是每个节点都用dfs去找最大值,显然1e6*1e6 超时了,只能60分从第一个节点开始遍历&…...
Vue3 + Three.js 场景编辑器开发实践
文章目录 前言项目背景与意义项目技术栈在线演示核心功能实现1. 智能化场景管理2. 专业级模型处理3. 可视化材质与照明4. 相机与渲染引擎5. 场景操作 项目优势开发目标1. 几何模型和模型导入,场景新建按钮增加2. 提供场景内容的可视化编辑功能3. 渲染器场景…...
Vue3 本地打包启动白屏解决思路!! !
“为什么我访问 http://127.0.0.1:5501/index.html 白屏,删了 index.html 再访问 / 就又活过来了?” —— 你的项目与 SPA 路由的“宫斗大戏” 一、问题复现 场景 本地通过 VSCode Live Server(或其他静态服务器)启动了打包后的 V…...
Ubuntu 安装 Docker 教程(官方推荐方式)
✅ 步骤 1:卸载旧版本(如果有) for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done---### ✅ 步骤 2:更新 APT 索引并安装依赖项bash sudo a…...
WPF 点击按钮,显示隐藏另一个控件
<Button Content"显示隐藏" Click"operationDetails_Click" /> private void operationDetails_Click(object sender, RoutedEventArgs e) { 另一个控件的Name.Visibility 另一个控件的Name.Visibility Visibility.Visible ? Visibility.Col…...
RBAC的使用
1、简述RBAC的作用及工作流程 Rbac基于角色访问控制,用于管理用户对集群资源的访问权限,通过定义角色和绑定规则,将用户与权限进行关联,作用:权限精细化管理,操作便捷与统一管理,动态调整权限。…...
QML中的3D功能--模型导入与修改
在Qt 3D中导入和修改3D模型是开发3D应用程序的基础。以下是详细的流程和技术方案: 一、模型导入基础 1. 支持的文件格式 Qt 3D支持多种3D模型格式: OBJ (Wavefront) FBX (Autodesk) DAE (Collada) GLTF/GLB (推荐格式) STL (3D打印格式) 2. 基本导入方法 qml import Qt3…...
树莓派超全系列教程文档--(33)树莓派启动选项
树莓派启动选项 启动选项start_file ,fixup_filecmdlinekernelarm_64bitramfsfileramfsaddrinitramfsauto_initramfsdisable_poe_fandisable_splashenable_uartforce_eeprom_reados_prefixotg_mode (仅限Raspberry Pi 4)overlay_prefix配置属…...
dotnet core webapi 实现 异常处理中间件
目录 第一步:创建异常处理中间件类(自定义响应格式) 第二步:在 Program.cs 中使用中间件 三、效果 第一步:创建异常处理中间件类(自定义响应格式) public static class ExceptionMiddleware…...
实现Azure Function安全地请求企业内部API返回数据
需要编写一个Function在Azure云上运行,它需要访问企业内部的API获取JSON格式的数据,企业有网关和防火墙,API有公司的okta身份认证,通过公司的域账号来授权访问,现在需要创建一个专用的域账号,让Function访问…...
实现Azure Databricks安全地请求企业内部API返回数据
需要编写一个Databricks在Azure云上运行,它需要访问企业内部的API获取JSON格式的数据,企业有网关和防火墙,API有公司的okta身份认证,通过公司的域账号来授权访问,现在需要创建一个专用的域账号,让Databrick…...
结合建筑业务讲述TOGAF标准处理哪种架构
TOGAF标准处理哪种架构 内容介绍业务架构业务策略,治理,组织和关键业务流程数据架构组织的逻辑和物理数据资产以及数据管理资源的结构应用架构待部署的各个应用程序,它们之间的交互以及与组织核心业务流程的关系的蓝图技术架构支持业务&#…...
深度学习--卷积神经网络CNN原理
文章目录 一、CNN图像原理1、了解CNN如何处理图像 二、CNN图像识别1、画面不变性2、主要表现1)平移不变性2)尺度不变性3)旋转不变性 3、传统神经网络1)数据预处理2)特征提取3)搭建神经网络模型4)…...
PostgreSQL 常用客户端工具
PostgreSQL 常用客户端工具 PostgreSQL 拥有丰富的客户端工具生态系统,以下是各类常用工具的详细分类和介绍: 一 图形化客户端工具 1.1 跨平台工具 工具名称特点适用场景许可证pgAdmin官方出品,功能全面开发/运维PostgreSQLDBeaver支持多…...
PostgreSQL数据库yum方式安装详解
PostgreSQL数据库yum方式安装 1. 基础环境配置2. 前期安装准备3. 软件安装3.1 YUM方式安装(PG 13)3.1.1 安装rpm仓库3.1.2 安装软件包PG133.1.3 初始化数据库3.1.4 启动数据库3.1.5 开机自启动3.1.6 编辑环境变量 4. 安装后配置 1. 基础环境配置 2. 前期…...
浅析vue2和vue3的区别
以下是 Vue 2 和 Vue 3 的主要区别: 一、核心特性 1. 响应式机制 Vue 2: 基于 Object.defineProperty 实现响应式。无法检测对象属性的新增和删除,需要使用 Vue.set 或 $set。Vue 3: 使用 Proxy 替代 Object.defineProperty。能够直接检测对象属性的新增和删除,无需额外方…...
【Linux我做主】make和makefile自动化构建
make和makefile自动化构建 make和makefile自动化构建github地址前言背景介绍为什么需要make和makefile? make和makefile解析什么是make和makefile依赖关系和依赖方法核心语法结构简单演示编译清理 多阶段编译示例 make时执行的顺序场景1:clean目标在前(特…...
spring boot应用部署IIS
Windows IIS 部署 Spring Boot 应用详细指南 本文档提供了在 Windows Server 上使用 IIS 部署 Spring Boot 应用的完整步骤和最佳实践。 目录 概述前期准备Spring Boot 应用准备安装配置必要组件配置 IIS 站点配置反向代理配置 Windows 服务配置应用自启动HTTPS 配置日志配置…...
Linux系统之部署TestNet资产管理系统
Linux系统之部署TestNet资产管理系统 一、TestNet 介绍1.1 TestNet简介1.2 主要特点1.3 主要使用场景 二、本次实践规划2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、部署TestNet系统4.1 下载T…...
@EnableAsync+@Async源码学习笔记之六
接上文,我们本文分析 AsyncExecutionAspectSupport 的源码: package org.springframework.aop.interceptor;import java.lang.reflect.Method; import java.util.Map; import java.util.concurrent.Callable; import java.util.concurrent.CompletableFu…...
SQL系列:常用函数
1、【MySQL】合并字段函数(列转行) 它可以将两个字段中的数据合并到一个字段中。 1)CONCAT函数 CONCAT函数可以将多个字段中的数据合并到一个字段中。它的语法格式如下: SELECT CONCAT(字段1,字段2,...字段N) FROM 表名;SELEC…...
Git 中修改某个特定的commit提交内容
在 Git 中修改某个特定的提交(commit)通常需要使用 交互式变基(Interactive Rebase) 或 修改提交(Commit Amend)。以下是不同场景下的具体操作步骤: 一、修改最近的提交(最新提交&am…...
FHS --- linux目录结构(部分目录解释)
根目录(/) 的意义和内容 : 根目录是整个系统最重要的一个目录,因为不但所有的目录都是由根目录衍生出来的,同时根目录也与开机/还原/系统修复等动作有关 。 由于系统开机时需要特定的开机软件、核心档案、开机所需程序…...
不带无线网卡的Linux开发板上网方法
I.MX6ULL通过网线上网 设置WLAN共享修改开发板的IP 在使用I.MX6ULL-MINI开发板学习Linux的时候,有时需要更新或者下载一些资源包,但是开发板本身是不带无线网卡或者WIFI芯片的,尝试使用网口连接笔记本,笔记本通过无线网卡连接WIFI…...