5.10-套接字通信 - C++
套接字通信
1.1 通信效率问题
-
服务器端
-
单线程 / 单进程
- 无法使用,不支持多客户端
-
多线程 / 多进程
- 写程序优先考虑多线程:
- 什么时候考虑多进程?
- 启动了一个可执行程序 A ,要在 A 中启动一个可执行程序 B
- 支持多客户端连接
-
IO 多路转接
-
单线程 / 进程
-
支持多客户端连接但是效率不是最高的
- 所有的客户端请求都是顺序处理的 -> 排队
-
多线程
int main() {// 1. 监听 fdint lfd = socket(); };// 2. 绑定bind();// 3. 监听listen();// 4. 初始化 epoll()int epfd = epoll_create(x);// 5. epooll 添加检测节点 -> lfdepoll_ctl(epfd, epoll_ctl_add, lfd, &ev);while (1){int num = epoll_wait(epfd, evs, 1024, NULL);for (int i = 0; i < num; i++){if (curfd == lfd){pthread_create(&tid, NULL, acceptConn, &epfd);// accept();}else{...// read();// write();}}} }
-
线程池
-
多个线程的一个集合,可以回收用完的线程
- 线程池的个数取决于业务逻辑
-
密集型业务逻辑:需要大量 cpu 时间进行数据处理
- 线程个数 == 电脑核心数
-
进行 io 操作
- 线程个数 == 两倍 cpu 核心数
-
- 线程池的个数取决于业务逻辑
-
不需要重复频繁地创建销毁线程
-
设计思路
1. 需要两个角色- 管理者 -> 1 个- 工作的线程 -> N 个 2. 管理者- 不工作(不处理业务逻辑,监测工作的线程的状态,管理线程的个数)- 假设工作线程不够用了,动态创建新的线程- 假设工作的线程太多了,销毁一部分工作的线程- 动态监测工作的线程的状态 3. 工作的线程- 处理业务逻辑 4. 需要一个任务队列- 存储任务 -> 唤醒阻塞线程 -> 条件变量- 工作的线程处理任务队列中的任务- 没有任务 -> 阻塞
-
-
-
-
-
-
客户端
// 创建TcpSocket对象 == 一个连接,这个对象就可以和服务器通信了,多个连接需要创建多个这样的对象 class TcpSocket { public:TcpSocket(){m_connfd = socket(af_inet, sock_stream, 0);}TcpSocket(int fd){m_connfd = fd; // 传递进行的fd是可以直接通信的文件描述符,不需要连接操作}~TcpSocket();/* 客户端 连接服务器 */int conectToHost(string ip, unsigned short port, int connecttime){connect(m_connfd, &serverAddress, &len);}/* 客户端 关闭和服务端的连接 */int disConnect();/* 客户端 发送报文 */int sendMsg(string sendMsg, int sendtime = 10000){senf(m_connfd, data, datalen, 0);}/* 客户端 接受报文 */string recvMsg(int timeout){recv(m_connfd, buffer, size, 0);return buffer;}private:int m_connfd; };
-
服务器
// 思想: 服务端不负责通信,只负责监听,如果通信使用客户端类 class TcpServer { public:// 初始化监听的套接字: 创建,绑定,监听TcpServer();~TcpServer(); // 在这里边关闭监听的fdTcpSocket* acceptConn(int timeout = 999999){int fd = accept(m_lfd, &address, &len);// 通信fd -> 类TcpSocket* tcp = new TcpSocket(fd);if (tcp != nullptr){return tcp;}return nullptr;}private:int m_lfd; // 监听的fd };
// 使用 void * callback(void* arg) {TcpSocket * tcp = (TcpSocket *) arg;tcp->sendMsg();tcp->recvMsg();tcp->disConnect();delete tcp; }int main() {TcpServer * server = new Tcpserver;while (1){TcpSocket * tcp = server->acceptConn();// 创建子进程 -> 通信pthread_create(&tid, NULL, callback, arg)}delete server;return 0; }
// 客户端程序 int main() {TcpSocket * tcp = new TcpSocket;tcp->ConnectToHost(ip, port, timeout);tcp->sendMsg();tcp->recvMsg();tcp->disConnect();delete tcp; }
2 套接字超时
套接字通信过程中的默认的阻塞函数
等待并接受客户端连接
通信、接受数据、发送数据、连接服务器时
设置超时处理的原因:不想让进程(线程)一直在对应为止阻塞
超时处理的思路:
- 定时器
sleep(10)
- 以上两种不可用,在指定时间内阻塞函数满足条件直接解除阻塞,以上两种不满足要求
- IO 多路转接函数
- 这些函数最后一个参数是设置阻塞的时长,如果有
fd
发生变化,函数直接返回- 帮助委托内核检测
fd
状态:读写异常
2.1 accept 超时
// 等待并接受客户端连接
// 如果没有客户端连接,一直阻塞
// 检测 accept 函数的 fd 读缓冲区就可以了
int accept(int sockfd, struct sockaddr * addr, socklen_t * addrlen);// 使用select 函数检测状态
int select(int nfds, fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout);
// 通信的fd放到 fd_set 中检测
if (ret == 0)
{// 超时
}
else if (ret == 1)
{// 有新连接accept(); // 绝对不阻塞
}
else
{// error, -1
}
读超时、写超时略
2.2 connect 超时
// 连接服务器 -> 处于连接过程中,函数不返回 -> 程序阻塞在这个函数上,可通过返回值判断是不是连接成功了
// 返回值 0,成功,-1,失败
// 该函数默认有一个超时处理:75s 或 175s- 设置 connect 函数操作的文件描述符为非阻塞- 使用 select 检测- 设置 connect 函数操作的文件描述符为阻塞 -> 状态还原
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);// 与上述同理
2.3 tcp 粘包问题
造成原因:
- 发送的时候,内核进行了优化,数据达到一定量发一次
- 网络环境不好,有延迟
- 接收方频率低,一次性读到了多条客户端发送的数据
解决方案:
- 发送的时候强制缓存区发送数据
- 在发送数据的时候添加包头
- 包头:一块内存,存储了当前消息的属性信息
- 属于谁:char[12]
- 有多大:int
- …
3 进程间通信:共享内存
-
使用流程
1. 向内核申请一块内存 -> 指定大小 2. 如果有两个进程需要进行通信,可以使用共享内存通信,先创建两个进程 3. 进程 A 和进程 B 分别和共享内存进程关联- 拿到共享内存的地址 -> 首地址 4. 两个进程可以公国这个首地址对共享内存进行读(写)操作 5. 如果这个进程不再使用这块共享内存,需要和共享内存断开连接- 进程退出对共享内存没有任何影响 6. 当不再使用共享内存的时候,需要将共享内存销毁
-
共享内存头文件
#include <sys/ipc.h> #include <sys/shm.h>
-
共享内存操作函数
-
创建或打开一块共享内存区
// 创建共享内存 // 共享内存已经存在 // 可以创建多块共享内存 int shmget(key_t key, size_t size, int sh mhflg);key:通过 key 记录共享内存在内核中的位置,为一个大于零的整数,等于 0 不行,随便指定一个就可以size:创建共享内存的时候指定共享内存的大小。如果已经创建,设为 0shmflg:创建共享内存的时候使用,指定打开文件的方式 返回值:成功:创建(打开)成功,得到一个整形数失败:-1// 应用 // 1. 创建共享内存 int shmid = shmget(100, 4096, IPC_CREAT | 0664); int shmid = shmget(200, 4096, IPC_CREAT | 0664); // 2. open share memory int shmid = shmget(100, 0, 0)
-
将当前进程与共享内存关联
void * shmat(int shmid, const void * shmaddr, int shmflg);参数:- shmid:通过这个参数访问共享内存,shmget() 的返回值- shmaddr:指定共享内存在内核中的位置,指定为空,委托内核寻找- shmflg:关联成功后对内存的操作权限- SHM_RDONLY:只读- 0:读写 成功:内存的地址 失败:(void *)-1// 函数调用: shmat(shmid, NULL, 0); // write on shm memcpy(ptr, "xxx", len); printf("%s", (char*)ptr);
-
depart shm
int shmdt(const void * shmaddr);arg: address of shmreturn:suc: 0fai: -1
-
control shm
int shmctl(int shmid, int com, struct shmid_ds * buf);arg:-shimd: reuturn value of shmget- cmd: operation to shm- IPC_STAT: get status of cmd- IPC_SET: set shm- IPC_RMID: mark shm to be destroyed- buf: as a struct can describe the status of shm reutrn value:succ: 0fail: -1// demo: destroy shm shmctl(shmid, IPC_RMID, nullptr);
demo: communication of processes
read:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h>int main() {// 1. open shmint shmid = shmget(100, 0, 0);// 2. relate shm with cur processvoid* ptr = shmat(shmid, NULL, 0);// 3. write on shmprintf("content: %s\n", (char *)ptr);printf("press any key to continue ...\n");getchar();// 4. release relevanceshmdt(ptr);// 5. destory shmshmctl(shmid, IPC_RMID, NULL);return 0; }
write:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/ipc.h> #include <sys/shm.h>int main() {// 1. create shmint shmid = shmget(100, 4096, IPC_CREAT|0664);// 2. relate shm with cur processvoid* ptr = shmat(shmid, NULL, 0);// 3. write on shmconst char * tmp = "this is a damo for shm ...";memcpy(ptr, tmp, strlen(tmp) + 1);printf("press any key to continue ...\n");getchar();// 4. release relevanceshmdt(ptr);// 5. destory shmshmctl(shmid, IPC_RMID, NULL);return 0; }
-
-
question:
- question 1: how dose the operation system know the number of process that relate with a shm?
- shm keep a struct
struct shmid_ds
, that has a membershm_nattch
. shm_nattch
records the number of being related process.
- shm keep a struct
- question 2: whether can call
shmctl
to destroyed a shm more than once?- yes
- because
shmctl
function is just marking a shm to be destroy, not destroying it directly. - when it was destroyed truly?
- when
shm_nattch == 0
- when
the commands to observe the shm:
ipcs -m
-
ftok
function prototypekey_t ftok(const char *pathname, int proj_id);- pathname: the absolute path- proj_id: only use the top 1 byte- value range: 1 - 255key_t t = fotk("/home/", 'a');
-
difference of shm and mmp
. . .
4 the API encapsulation of shm
class BashShm
{
public:BashShm(int key); // open a shm according a given key.BashShm(string path); // **with no size**, according to string path -> int key, open a shm.BashShm(int key, int size); // create a shm by the given key and size.BashShm(string path, int size); // string -> key, according to size.void * mapshm(){m_ptr = shmat(shmid);return shmat();}int unmapshm(){return shmdt(m_ptr);}int delshm(){return shmctl(shmid);}private:int m_shmid; // reuturn value of `shmat()`void * m_ptr
}
相关文章:
5.10-套接字通信 - C++
套接字通信 1.1 通信效率问题 服务器端 单线程 / 单进程 无法使用,不支持多客户端 多线程 / 多进程 写程序优先考虑多线程:什么时候考虑多进程? 启动了一个可执行程序 A ,要在 A 中启动一个可执行程序 B 支持多客户端连接 IO 多…...
【Linux】Linux内核的网络协议之socket理解
1. Socket(套接字) 的本质 它是应用程序与网络协议栈之间的编程接口(API),用于实现网络通信。 Socket 并不是一个物理设备,而是一个抽象层为应用程序提供统一的网络操作接口(如 send()、recv()…...
仿函数和函数对象
1. 概念解读:什么是“函数”和“函数对象”? 核心概念一句话总结 仿函数(Functor) 函数对象(Function Object) 它们本质是一个对象(Object),但可以像函数(Fu…...
Kubernetes控制平面组件:Kubelet 之 Static 静态 Pod
云原生学习路线导航页(持续更新中) kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计(一)Kubernetes架构原则和对象设计(二)Kubernetes架构原则和对象设计(三)Kubernetes控…...
Django 项目的 models 目录中,__init__.py 文件的作用
在 Django 项目的models/init.py文件中,这些导入语句的主要作用是将各个模型类从不同的模块中导入到models包的命名空间中。这样做有以下几个目的: 简化导入路径 当你需要在项目的其他地方使用这些模型时,可以直接从models包导入,…...
学习日志04 java
PTA上的练习复盘 java01 编程题作业感悟: 可以用ai指导自己怎么调试,但是不要把调代码这过程里面的精华交给ai,就是自己去修正错误不能让ai代劳!~~~ 1 scanner.close() Scanner *** new Scanner(System.in); ***.close(); …...
vue-pdf-embed预览PDF
一、vue-pdf-embed 链接:Yarn 1、安装插件 npm install vue-pdf-embed 2、文件中引入(分页效果已实现,样式请自行修改) <template><div class"download-pdf-preview" style"height: 450px; border:1…...
C++GO语言微服务之Dockerfile docker-compose
目录 01 01-知识点概述 02 02-dockerfile复习 03 03-环境变量ENV的使用 04 04-WORKDIR的使用 05 05-USER和ARG的使用 06 06-ONBUILD的使用 07 07-dockerfile的缓存相关的参数 08 08-dockerfile的编写 09 09-测试-没成功-好像是网不行 01 10-docker-compose介绍 02 11…...
【漫话机器学习系列】255.独立同分布(Independent and Identically Distributed,简称 IID)
深入理解独立同分布(IID):机器学习与统计学的基石 在机器学习、深度学习、统计建模等领域,我们经常会遇到一个重要假设:独立同分布(Independent and Identically Distributed,简称 IID…...
树莓派4 yolo 11l.pt性能优化后的版本
树莓派4 使用 Picamera2 拍摄图像,然后通过 YOLO11l.pt 进行目标检测,并在实时视频流中显示结果。但当前的代码在运行时可能会比较卡顿,主要原因包括: picam2.capture_array() 是一个较慢的操作;YOLO 推理可能耗时较长…...
AD22 快速定义PCB板框与DXF导入定义
自行定义板框 1. 初步评估:选中所有的器件,选中‘在矩形区域排列’ 将元件放好后,可以再将元件紧凑一下 2. 设置原点,并在下方选中机械一层 从原点出发,点击快捷键PL 画框线 3. 对线条长度取整,且最好是5…...
LInux系统文件与目录管理(二)
提示:第二部分对第一部分收尾 文章目录 常见的命令如下一、文件查看命令1. more命令2.less命令3.head命令4.tail命令5.nl命令(了解)6.创建目录命令7.创建文件命令>: 覆盖重定向>>: 追加重定向 8.touch命令9.echo命令10.文件或目录复…...
Redisson在业务处理中失败后的应对策略:保障分布式系统的可靠性
分布式系统中的数据一致性与高可用性一直是开发者面临的难题。作为Redis官方推荐的Java客户端,Redisson凭借其强大的分布式能力成为解决这些问题的利器。但在实际业务场景中,网络抖动、资源竞争、节点故障等问题可能导致操作失败,本文将深入探…...
windows下docker 运行 ros2humble arm64
目前要想运行arm版ros humble 目前最好的解决方案是使用qemu模拟。 1.拉取 ubuntu22.04 docker pull ubuntu:22.04 --platformarm642.安装小鱼ros2 humble wget http://fishros.com/install -O fishros && . fishros3.安装eqmu docker run --rm --privileged multia…...
表的增删改查 -- 2
目录 3、查询(R) 3.7、条件查询:where 3.8、分页查询:limit 3.9、查询总结 4、修改(U) 5、删除(D) 3、查询(R) 3.7、条件查询:where selec…...
Linux系统管理与编程20:Apache
兰生幽谷,不为莫服而不芳; 君子行义,不为莫知而止休。 做好网络和yum配置,用前面dns规划的www的IP进行。 #!/bin/bash #----------------------------------------------------------- # File Name: myWeb.sh # Version: 1.0 # …...
dfs 第一次加训 详解 下
目录 P1706 全排列问题 思路 B3618 寻找团伙 思路 B3621 枚举元组 思路 B3622 枚举子集(递归实现指数型枚举) 思路 B3623 枚举排列(递归实现排列型枚举) B3625 迷宫寻路 思路 P6183 [USACO10MAR] The Rock Game S 总结…...
vue2/3 中使用 @vue-office/docx 在网页中预览(docx、excel、pdf)文件
1. 安装依赖: #docx文档预览组件npm install vue-office/docx vue-demi0.14.6#excel文档预览组件npm install vue-office/excel vue-demi0.14.6#pdf文档预览组件npm install vue-office/pdf vue-demi0.14.6 vue2.6版本或以下还需要额外安装 vue/composition-api …...
Excel表的导入与导出
Excel表的导入与导出 根据excel表来建立所需的数据库表格 <dependency><groupId>com.auth0</groupId><artifactId>java-jwt</artifactId><version>3.10.3</version></dependency><dependency><groupId>cn.hutool&…...
Redis 中常见的数据类型有哪些?
Redis 常见的数据类型包括 5 种基础类型(String、Hash、List、Set、Zset)和 3 种特殊类型(HyperLogLog、Bitmap、Geospatial)。以下是详细说明: 一、5 种基础数据类型 1. 字符串(String) 特点…...
消息队列如何保证消息可靠性(kafka以及RabbitMQ)
目录 RabbitMQ保证消息可靠性 生产者丢失消息 MQ丢失消息 消费端丢失了数据 Kakfa的消息可靠性 生产者的消息可靠性 Kakfa的消息可靠性 消费者的消息可靠性 RabbitMQ保证消息可靠性 生产者丢失消息 1.事务消息保证 生产者在发送消息之前,开启事务消息随后生…...
基于STM32、HAL库的BMP390L气压传感器 驱动程序设计
一、简介: BMP390L 是 Bosch Sensortec 生产的一款高精度气压传感器,专为需要精确测量气压和海拔高度的应用场景设计。BMP390L 具有更低的功耗、更高的精度和更快的响应速度。 二、硬件接口: BMP390L 引脚STM32L4XX 引脚说明VDD3.3V电源GNDGND地SCLPB6 (I2C1 SCL)I2C 时钟线…...
QMK键盘固件中LED锁定指示灯的配置与使用详解(实操部分+拓展)
QMK键盘固件中LED锁定指示灯的配置与使用详解 大家好!今天就跟大家一起探索QMK固件中LED锁定指示灯的配置与使用。无论你是键盘DIY新手还是老司机,相信这篇教程都能帮你解锁新技能! 一、基础配置:定义LED引脚 在QMK固件中配置LED锁定指示灯非常简单,只需在config.h文件…...
【日撸 Java 三百行】Day 12(顺序表(二))
目录 Day 12:顺序表(二) 一、顺序表的方法 1. 顺序查找 拓展:顺序查找中的哨兵思想 2. 插入 3. 删除 二、代码及测试 拓展: 小结 Day 12:顺序表(二) Task: 今天…...
Python爬虫实战:研究ajax异步渲染加密
一、引言 在当今数字化时代,数据已成为推动各行业发展的核心驱动力。网络爬虫作为一种高效的数据采集工具,能够从互联网上自动获取大量有价值的信息。然而,随着 Web 技术的不断发展,越来越多的网站采用了 AJAX(Asynchronous JavaScript and XML)异步渲染技术来提升用户体…...
Golang企业级商城高并发微服务实战
Golang企业级商城高并发微服务实战包含内容介绍: 从零开始讲了百万级单体高并发架构、千万级微服务架构,其中包含Rpc实现微服务、微服务的跨语言调用jsonrpc和protobuf、protobuf的安装、protobuf高级语法、protobuf结合Grpc实现微服务实战、微服务服务…...
从经典力扣题发掘DFS与记忆化搜索的本质 -从矩阵最长递增路径入手 一步步探究dfs思维优化与编程深度思考
1引子: DFS和递归法的一道经典例题矩阵最长递增子序列这个题写完之后脑袋产生了许多突发奇想: 1 第一个堆栈代码段这些底层C语言内部管理的工具它是怎么进行内存分配的?能不能深究? 2 第二个这个DFS和计划数组存储的思路到底抽象…...
我开源了一个免费在线工具!UIED Tools
UIED Tools - 免费在线工具集合 最近更新:修改了文档说明,优化了项目结构介绍 这是设计师转开发的第一个开源项目,bug和代码规范可能有些欠缺。 这是一个功能丰富的免费在线工具集合网站,集成了多种实用工具,包括 AI …...
geoserver发布arcgis瓦片地图服务(最新版本)
第一步:下载geoserver服务,进入bin目录启动 需要提前安装好JDK环境,1.8及以上版本 安装完成,页面访问端口,进入控制台界面,默认用户名密码admin/geoserver 第二步:下载地图 破解版全能电子地图下载器&…...
RN 鸿蒙混合开发实践(踩坑)
#三方框架# #React Native # 1 。环境配置; 安装 DevEco 开发工具; Node 版本16; hdc环境配置 hdc 是 OpenHarmony 为开发人员提供的用于调试的命令行工具,鸿蒙 React Native 工程使用 hdc 进行真机调试。hdc 工具通过 OpenHa…...
2025年阿里云ACP大数据分析师认证模拟试题(附答案解析)
这篇文章的内容是阿里云ACP大数据分析师认证考试的模拟试题。 所有模拟试题由AI自动生成,主要为了练习和巩固知识,并非所谓的 “题库”,考试中如果出现同样试题那真是纯属巧合。 1、ABC公司现有大量的图片和视频信息,以下哪种产…...
go语言实现IP归属地查询
效果: 实现代码main.go package mainimport ("encoding/json""fmt""io/ioutil""net/http""os" )type AreaData struct {Continent string json:"continent"Country string json:"country"ZipCode …...
Qt中解决UI线程阻塞导致弹窗无法显示的两种方法
在Qt应用程序开发中,我们经常会遇到这样的问题:当执行一个耗时操作时,整个界面会卡住,无法响应任何用户操作,甚至连一个简单的提示弹窗都无法正常显示。本文将介绍两种解决这个问题的方法,并通过完整的代码示例进行说明。 问题描述 先来看一个常见的错误示例: #inclu…...
位运算题目:黑板异或游戏
文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法代码复杂度分析 题目 标题和出处 标题:黑板异或游戏 出处:810. 黑板异或游戏 难度 8 级 题目描述 要求 给定一个整数数组 nums \texttt{nums} nums,表示写在黑板…...
LegoGPT,卡内基梅隆大学推出的乐高积木设计模型
LegoGPT 是由卡内基梅隆大学开发的一款创新性乐高积木设计模型,能够根据用户的文本提示生成结构稳固、可组装的乐高模型。该模型基于自回归语言模型和大规模乐高设计数据集进行训练,用户只需输入简单的文字描述,LegoGPT 就能逐步构建出物理稳…...
深度 |国产操作系统“破茧而出”:鸿蒙电脑填补自主生态空白
真心为国内能有像华为这样的技术型公司而自豪,一步步突围技术封锁。从这篇信息,可以给软件从业者一个启示:鸿蒙生态将是一个新的机会,值得好好把握。 鸿蒙电脑正成为中国电子信息技术新坐标。 超10亿鸿蒙生态设备、2800家鸿蒙智…...
【Python】Python常用数据类型判断方法详解
在Python编程中,准确判断数据类型是处理逻辑分支、类型转换和异常处理的基础。本文结合核心方法与实践场景,系统介绍type()、isinstance()等常用判断方式,并分析其适用性与最佳实践。 一、直接类型判断方法 type()函数 • 功能:返回对象的精确类型,适用于简单类型判断。 •…...
【美国将取消对能源之星支持 严重影响AI服务器】
1992年美国政府在共和党执政期间推出了影响深远的“能源之星”计划(Energy Star),很多人可能并不知道能源执行计划,但这个蓝色星星标签估计大多数人都不会陌生。能源之星计划从推出以来不止得到各类消费电子制造商认可,…...
《 C++ 点滴漫谈: 三十七 》左值?右值?完美转发?C++ 引用的真相超乎你想象!
摘要 本文全面系统地讲解了 C 中的引用机制,涵盖左值引用、右值引用、引用折叠、完美转发等核心概念,并深入探讨其底层实现原理及工程实践应用。通过详细的示例与对比,读者不仅能掌握引用的语法规则和使用技巧,还能理解引用在性能…...
【生产实践】Linux中/usr/bin、/usr/sbin与/usr/local的关系解析(2025年技术规范)
一、核心定位与功能划分 /usr/bin:用户级通用命令库 • 定位:存储系统预装的用户级可执行文件,这些命令通常由Linux发行版官方软件包管理器(如APT、YUM)安装,属于系统默认功能的一部分。 • 示例命令&#…...
数据可视化:用一张图讲好一个故事
在这个信息爆炸的时代,数据无处不在,但如何让复杂的数据变得通俗易懂?数据可视化就是一把神奇的钥匙。它不仅能将枯燥的数字转化为生动的图像,还能挖掘出数据背后隐藏的故事。然而,很多人对数据可视化的理解还停留在表…...
C++获取目录中所有图片路径的函数get_image_paths解析
本文将全面解析一个用于获取目录中图片路径的C函数get_image_paths,从基础语法到高级概念,涵盖C标准库、文件系统操作、异常处理等多个方面。 原始代码 std::vector<std::string> get_image_paths(const std::string& directory_path) {log_…...
物联网无线传感方向专业词汇解释
涡旋电磁波(VEMW):一种具有轨道角动量的电磁波,其特性在于能够在传播过程中携带额外的相位信息,从而增加通信系统的容量和灵活性。波前:波动传播过程中,同一时刻振动相位相同的所有点构成的几何曲面,代表波…...
【C语言指针超详解(五)】--回调函数,qsort函数的理解和使用,qsort函数的模拟实现
目录 一.回调函数 1.1--回调函数的概念 1.2--回调函数改造计算器程序 二.qsort函数的理解和使用 2.1--qsort函数的理解 2.2--使用qsort函数排序整型数据 2.3--使用qsort函数排序结构数据 三.qsort函数的模拟实现 🔥个人主页:草莓熊Lotso的个人主…...
【Linux网络】————HTTP协议详解
作者主页: 作者主页 本篇博客专栏:Linux 创作时间 :2025年5月11日 1. HTTP 协议介绍 基本介绍: http协议全称:超文本传输协议,适用于从万维网服务器传输超文本到本地的传送协议。HTTP是一种应用层协议…...
使用WinSW工具将exe注册为window服务
下载工具WinSW(工具在GitHub上 打不开就需要魔法VPN) 文件准备 将以下文件放在同一个目录(例如:WebSocketService 文件夹)中: WebScoket.exe WinSW-x64.exe WebScoketService.xml ← 服务配置文件 install_service.bat ←…...
远程命令执行RCE概述
远程命令执行RCE诞生于1997年,比SQL注入早1年,据说当时的程序员发现在网站里可以随意的删除网页,就像删除本地文件一样简单,但是这种场景相对不多,因此没有SQL注入广泛,早期的web攻击像现在的护网一样&…...
在 .NET 8 开发的WinForms 程序中展示程序版本号的几种方式
前言 欢迎关注dotnet研习社,今天我们讨论一个Winform开发中的一个常见的需求内容“关于程序的版本号显示”。 在 WinForms 桌面应用程序开发中,向用户显示当前程序的版本号是一个常见的需求,尤其是在产品发布、更新提示或技术支持场景中尤为…...
[特殊字符] Spring Cloud 微服务项目中 common 模块依赖导致网关启动失败的排查与解决
在进行微服务开发时,我们通常会抽取一个 common 公共模块,封装一些通用配置类、工具类、拦截器、常用组件依赖等,供多个微服务共享使用。 但近期在实际开发中,出现了一个典型问题:在 Gateway 网关模块中引入 common 后…...
Java SpringMVC 和 MyBatis 整合关键配置详解
目录 一、数据源配置二、MyBatis 工厂配置三、Mapper 扫描配置四、SpringMVC 配置五、整合示例实体类Mapper 接口Mapper XML 文件Service 类控制器JSP 页面六、总结在 Java Web 开发中,SpringMVC 和 MyBatis 是两个常用框架。SpringMVC 负责 Web 层的请求处理和视图渲染,MyBa…...