- 博客(108)
- 收藏
- 关注
原创 如何使用Docker一键本地化部署LibrePhotos搭建私有云相册
你是不是也经常对着手机里那一堆珍贵的照片发愁,心里想着:‘这要是被谁偷偷看了可咋办?’别担心,今天我就给大家带来一个超实用的解决方案——!这个开源自托管神器不仅能够完美替代Google Photos,还能让你牢牢把控自己的数据安全。更重要的是,即使没有公网IP或域名也不怕,因为我们有cpolar这位超级英雄帮忙打通内外网,无论你身处何方都能轻松管理照片库。快来跟我一起学习如何在本地Linux上搭建属于你的私人照片空间吧!
2025-02-27 15:35:28
1143
12
原创 树莓派5新玩法:使用VNC轻松实现远程控制Raspberry Pi实操秘籍
大家好!今天我要教你们如何在树莓派5上安装Raspberry Pi OS,并配置SSH和VNC权限。通过这些步骤,你将能够在Windows电脑上使用VNC Viewer,结合Cpolar内网穿透工具,实现长期的公网远程访问管理本地树莓派。听起来是不是很酷?跟着我一步步来吧!树莓派因其小巧的尺寸和强大的功能而受到广泛欢迎。无论是作为教育工具、家庭娱乐中心还是各种项目的核心控制器,树莓派都是一个绝佳的选择。对于许多用户来说,通过VNC远程连接是利用树莓派的一种关键方式。
2024-12-12 22:07:58
1341
13
原创 CasaOS部署小雅AList
嘿,大家好!之前我们分享了如何在CasaOS玩客云Docker中部署AList,并通过cpolar内网穿透实现远程离线下载文件上传网盘。很多小伙伴觉得这个玩法很有趣,还有一些朋友希望了解如何在玩客云上部署小雅AList并使用AList挂载,这样查看资源更加方便,内容也更丰富。今天就来给大家揭秘这个简单又实用的技巧,让你们在没有公网IP的情况下也能轻松访问海量资源!流程同样非常简单,一行命令就能实现。
2024-12-03 19:21:52
2167
13
原创 轻松几步把云音乐播放器YesPlayMusic搬到本地远程也能畅听无阻
今天给大家带来一个超实用的教程:如何在本地快速搭建YesPlayMusic云音乐播放器,并结合cpolar内网穿透工具实现随时随地远程访问局域网内的音乐播放器,畅享无界音乐之旅。YesPlayMusic 是一款优秀的个人音乐播放器,它通过Docker方式可以轻松部署在你的本地服务器上。其简洁清爽的操作界面、快速准确的搜索功能,以及自定义歌单和歌词显示,为用户提供了极致的播放体验。如果你是网易云音乐的忠实粉丝,YesPlayMusic绝对是一个不容错过的选择。【视频教程】
2024-11-25 19:26:54
943
12
原创 C++11实现线程库
该线程池最终的一个函数就是想线程池中push任务的函数,用户可以自己要执行的函数以及参数传递进来,然后线城池启动线程进行执行,通过函数返回值的方式让用户拿到数据。因为用户要执行的参数个数类型是不确定的,所以该函数是一个模板函数,第一个模板参数是要执行的函数,第二个是可变参数模板,用来接收用户的参数,在函数内部通过绑定参数,来得到一个无参的可执行对象,通过构造lambda的方式来添加进入任务队列。本篇博客通过packaged_task 封装一个可以让用户拿到线程结果的线程池。
2024-11-17 22:32:43
255
13
原创 基于Zynq FPGA对雷龙SD NAND的测试
雷龙的SD NAND有很多型号,在测试中使用的是CSNP4GCR01-AMW与CSNP32GCR01-AOW。芯片是基于 NAND FLASH 和 SD控制器实现的SD卡。具有强大的坏块管理和纠错功能,并且在意外掉电的情况下同样能保证数据的安全。其特点如下:接口支持SD2.0 2线或4线;电压支持:2.7V-3.6V;默认模式:可变时钟速率0 - 25MHz,高达12.5 MB/s的接口速度(使用4条并行数据线)
2024-11-12 13:54:42
2155
19
原创 通过muduo库函数实现protobuf通信协议
然后我们需要从安装的muduo库的muduo/examples/protobuf/codec路径中参考server.cc和client.cc来编写我们的代码,这里我们需要把codec.cc codec.h dispatcher.h 拷贝到我们的项目路径中。但是在实际的网路通信中,由于TCP通信时面向字节流的,所以序列化和解决粘包问题是必须的。所以我们在通信前就需要自己定制协议,在muduo库中,陈硕大佬已经定制好了一套基于protobuf序列化的协议,我们只需要通过接口进行使用就可以了。
2024-11-03 11:25:41
896
16
原创 muduo库简介
Muduo由陈硕⼤佬开发,是⼀个基于非阻塞IO和事件驱动的C++⾼并发TCP⽹络编程库。因为muduo库不管是服务端还是客⼾端都是异步操作,对于客户端来说如果我们在连接还没有完全建立成功的时候发送数据,这是不被允许的,所以还需要CountDownLatch类来进行同步控制。该类最重要的就是一个loop方法,用来开启事件循环,这个端口是一个死循环端口,开启之后程序就在监听对应事件的发生了。这个类最常用的就是retrieve*函数了,库里提供了很多,可以根据自己的需求使用,这个函数可以拿到对端发来的消息。
2024-10-25 17:02:23
999
14
原创 protobuf 未知字段的获取
未知字段就是服务器可能新增了一个字段,但是客服端的proto文件中并没有添加,那么服务器发来的序列化数据,在客服端进行反序列化之后,这个新增的字段在proto3.5之前是会被之久抛弃的,但是在proto3.5之后会被保存哎未知字段中。有了上述的理解之后就可以尝试拿一下未知字段的内容了,假设我们现在有一个PeopleInfo消息在contacts命名空间中,现在有一个消息实例peo,那么可以通过下述代码来拿到未知消息字段的变好以及内容。UnknownField类中就包含了未知消息的具体内容。
2024-10-20 17:53:17
638
13
原创 Ubuntu下载protobuf
如果我们在执行configure是修改安装⽬录,那么还需要在/etc/profile 中添加⼀些内容。进入之后执行autogen.sh,但如果下载的是具体的某一门语言,不需要执行这⼀步。如果要在 C++ 下使⽤ ProtoBuf,可以选择cpp.zip。5 ⽣成 protobuf-21.11 ⽂件,进⼊⽂件。然后重新执行以下 /etc/profile文件即可。希望支持全部语言,选择 all.zip。执⾏configure,有两种执行方式。2 下载protobuf。然后把下面内容拷贝过去。
2024-10-19 13:12:01
766
14
原创 【QT】QWidget 重要属性
在Qt开发中, 可以通过将资源文件添加到项⽬中来⽅便地访问和管理这些资源. 这些资源⽂件可以位于qrc⽂件所在⽬录的同级或其录下. 在构建程序的过程中, Qt 会把资源⽂件的⼆进制数据转成 cpp 代码, 编译到 exe 中. 从而使依赖的资源变得 “路径无关”.如果我们把图片⽂件放到构建目录中, 可能在不小心删除后就丢失了. 我们还是希望能够把图片和源代码放到⼀起, 并且使我们的程序无论拷贝到任何位置中都能正确使⽤图片.qrc 机制帮我们自动完成了上述工作, 更方便的来管理项目依赖的静态资源.
2024-09-26 22:41:27
1189
19
原创 Git常用指令
git commit 后⾯的 -m 选项,要跟上描述本次提交的 message,由⽤⼾⾃⼰完成,这部分内容绝对不能省略,并要好好描述,是⽤来记录你的提交细节,是给我们自己看的。–global 是⼀个可选项,如果使⽤了该选项,表⽰这台机器上所有的 Git 仓库都会使⽤这个配置。标签 tag ,可以简单的理解为是对某次 commit 的⼀个标识,相当于起了⼀个别名。Git 还提供可以创建带有说明的标签,⽤-a指定标签名,-m指定说明文字。在Git中打标签⾮常简单,⾸先,切换到需要打标签的分支上。
2024-09-20 19:35:18
1433
18
原创 孩子们的游戏(约瑟夫环问题)
其中,有个游戏是这样的:首先,让 n 个小朋友们围成一个大圈,小朋友们的编号是0~n-1。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0…使用数组模拟,但是需要注意取模操作,本质也是模拟环形队列,暴力代码不太好写,所以比较推荐第二种方法,也就本篇博客主讲的方法,动态规划。可以使用环形队列,模拟题目要求,每当到m - 1个个孩子的时候就从队列中删除,依次循环,直到剩下一个孩子。所以现在假设有i个孩子维成一圈。
2024-09-12 23:39:13
1041
18
原创 【负载均衡式在线OJ】Compile_server 模块
所以我们就需要根据文件名来形成这三个文件,然后进行重定向,如果这个程序需要输入就从对应的文件中读取,当然最后执行完之后需要的结果也会在标准错误对应的文件中,我们只需要将这三个文件创建好,然后只关心运行成功与否就可以了,因此对于父进程来说,一定是要关心子进程的运行状态的,如果程序运行成功了,那就返回就好了,如果出现异常运行失败了,一定会收到某种信号,就把收到的对应信号进行返回,所以对于这个函数来说,返回值>0 运行异常, 返回值 = 0 运行成功,结果不确定, 返回值 <0 程序内部出错了(打开文件等)。
2024-09-03 09:06:54
885
3
原创 【负载均衡式在线OJ】oj_server模块
这个模块是我们的核心逻辑控制模块,当用户请求我们全部题目列表时我们需要给用户返回一个带有全部题目列表的页面,所以我们需要一个获取全部题目列表的函数,这个函数需要先通过Model木块获取全部的题目信息,然后把全部的题目信息给View的渲染全部题目列表网页的函数,得到模板网页和我们的数据一起渲染后的网页,返回给用户,当然用户也可能请求单张网页,和获取全部的题目列表的方式一样,先通过Model获取指定题目的信息,然后交给View的渲染单张网页的函数,然后把结果返回给用户就可以了。主要采用MVC模式的编写。
2024-08-27 21:19:59
1199
3
原创 【负载均衡式在线OJ】项目设计
oj_server给用户提供题目网页,可以获取用户在浏览器中提交的代码,而compile_server可以存在很多个,然后oj_server负载均衡式的让每个compile_server负载均衡的帮用户编译处理代码,然后在通过oj_server返回给用户让用户看到。
2024-08-27 21:19:48
493
原创 MySQL事务
事务就是一组DML语句组成,这些语句在逻辑上存在相关性,这一组DML语句要么全部成功,要么全部失败,是一个整体。MySQL提供一种机制,保证我们达到这样的效果。事务还规定不同的客户端看到的数据是不相同的。事务就是要做的或所做的事情,主要用于处理操作量大,复杂度高的数据。原子性(Atomicity,或称不可分割性):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。
2024-08-13 18:09:12
1377
20
原创 MySQL索引
而此时IO的基本单位就是Page。页目录中存数据的主键和对应数据的地址,通过每个几个数据存一个,因为主键是有序的,可以通过比较找到就可以大概定位到那个数据附近的地址,可能还需要遍历,但是这次遍历的代价就很低了。目录页的本质也是页,普通页中存的数据是用户数据,而目录页中存的数据是普通页的地址。这时我们就可以使用一个目录项来指向某一页,而这个目录项存放的就是将要指向的页中存放的最小数据的键值,和页内目录不同的地方在于,这种目录管理的级别是页,而页内目录管理的级别是行,其中,每个目录项的构成是:键值+指针。
2024-08-08 23:42:26
1023
23
原创 MySQL表的约束
当我们对stu和myclass建立了外键约束后,stu的class_id就只能是myclass中id列的值,如果是别的MySQL就会拦截,同理如果我们想要删除是myclass中id列的值,如果stu的class_id还有对应的值,那么MySQL也会拦截不让删除。这个世界是数据很多都是相关性的,建立外键的本质其实就是把相关性交给mysql去审核了,提前告诉mysql表之间的约束关系,那么当用户插入不符合业务逻辑的数据的时候,mysql不允许你插入。默认值的生效:数据在插入的时候不给该字段赋值,就使用默认值。
2024-08-05 15:54:20
1900
21
原创 MySQL的数据类型
varchar的(L)中L表示的是最大的字符长度,但是MySQL会根据我们实际存入的大小为我们开辟空间,就类似于我们顺序表中的capacity,但是因为这样就需要多开1~3个字节为我们维护实际用来多少空间的信息,所以如果varchar存满的话,有3字节是存在维护信息的,实际存储的65532个字节。如果定义的是float(4,2) unsigned 这时,因为把它指定为无符号的数,范围是 0 ~ 99.99,所以浮点数和整型不一样,浮点数定义unsigned 会使数据表示范围减少一半。
2024-08-04 11:42:56
1389
17
原创 IO多路转接
调用epoll_create创建一个epoll模型;调用epoll_ctl, 将要监控的文件描述符进行注册;调用epoll_wait, 等待文件描述符就绪;
2024-08-03 23:40:01
1152
7
原创 MySQL的库操作和表操作
为保存应用中实体的数据,一般会在数据库中创建多个表,以保存程序中实体的数据。在项目实际开发中,经常修改某个表的结构,比如字段名字,字段大小,字段类型,表的字符集类型,表的存储引擎等等。如果备份一个数据库时,没有带上-B参数, 在恢复数据库时,需要先创建空数据库,然后使用数据库,再使用source来还原。执行删除之后,数据库内部看不到对应的数据库,对应的数据库文件夹被删除,级联删除,里面的数据表全部被删。db1.sql 文件里的内容,其实把我们整个创建数据库,建表,导入数据的语句都装载这个文件中。
2024-07-28 22:59:36
1387
18
原创 MAC、ARP、NAT
所以对于一次ARP的请求,不管是MAC报头还是ARP报头的目的以太网地址都是广播地址FF:FF:FF:FF:FF:FF这个局域网的所有主机都会对这个报文进行解析,得到ARP的数据报,对比目的IP之后是自己的就留下构建应答报文,不是话就丢弃,应答因为知道了对方的MAC地址,就不需要进行广播了,所以其他的主机收到了并不会对MAC报头进行解析,直接丢弃,所以请求和应答各个主机的做法也是不同的。如果不符,则直接丢弃。在网络通讯时,源主机的应用程序知道目的主机的IP地址和端口号,却不知道目的主机的硬件地址;
2024-07-26 15:15:24
1969
20
原创 IP协议和路由转发
路由表的Destination是目的网络地址,Genmask是子网掩码,Gateway是下一跳地址,Iface是发送接口,Flags中的U标志表示此条目有效(可以禁用某些 条目),G标志表示此条目的下一跳地址是某个路由器的地址,没有G标志的条目表示目的网络地址是与本机接口直接相连的网络,不必经路由器转发。每一个局域网都会存在自己专属的和局域网的网络号,而路由的过程就是不断的比对网络号进行路由,路由到局域网在根据主机号找到对应的主机,所以IP就提供了将数据包从A主机送到B主机的能力。网关就是下一跳的地址。
2024-07-24 19:31:27
1582
21
原创 TCP协议
首先建立连接是需要有成本的,不管是客户端还是服务器,都是需要成本的,如果是一次握手,单台主机就可以通过某种手段大量的向服务器发送请求,这样服务器直接就建立连接的话,单台主机就可能使服务器瘫痪,二次握手也是这样,收到客户端的的请求就建立连接,也会导致这样的问题,这样大量的向服务器发送SYN的问题为iSYN洪水问题。如果是三次握手,就保证了一定是客户端先建立连接,然后才是服务器建立连接,这样就不容易出现上述的问题,当然上述的问题对于三次握手依然存在,但是想要单台主机就做到就比较困难了。为什么要进行三次握手。
2024-07-19 16:16:40
2636
27
原创 UDP协议
所以UDP在发送报文前只需要把把头的结构化字段填好,然后防止报文的前面就可以像服务器进行请求了,但是不管是服务器还是客服端,都一定存在大量的UDP报文,所以OS也一定要对这么多的报文进行管理,所以OS也会存在对报文描述的结构体,报文本质就是数据,所以就是一段缓冲区,所以描述报文的结构体里面一定会存在指针。UDP的报头非常简单,存在16位源端口和16为目的端口,16位UDP长度, 表示整个数据报(UDP首部+UDP数据)的最大长度,如果校验和出错, 就会直接丢弃。UDP协议是传输层的协议,是在应用层之下的。
2024-07-17 18:11:24
1184
18
原创 HTTPS
数字指纹(数据摘要),其基本原理是利⽤单向散列函数(Hash函数)对信息进行运算,⽣成⼀串固定⻓度的数字摘要。数字指纹并不是⼀种加密机制,但可以⽤来判断数据有没有被窜改。摘要常见算法:有MD5、SHA1、SHA256、SHA512等,算法把⽆限的映射成有限,因此可能会有碰撞(两个不同的信息,算出的摘要相同,但是概率非常低)摘要特征:和加密算法的区别是,摘要严格意义不是加密,因为没有解密,只不过从摘要很难反推原信息,通常用来进行数据对比。
2024-07-16 17:41:48
1686
15
原创 守护进程(精灵进程)
因为已经成为一个独立的会话,已经没必要和用户交互什么的了,但是代码中可能还存在打印什么的函数,所以可以把标准输入输出错误流重定向给/dev/null 这个文件是Linux中都有的一个文件,Linux会自动的把写入到这里的内容丢弃。每次我们远端登录Linux,OS会给我提供bash和一个终端,用来给我们用户提供命令行服务,这就叫做一个会话,然后我们在该终端下启动的所有进程,都是默认在当前会话中的一个进程组(一个进程也可以自成进程组)。守护进程是一个独立的会话,不隶属于任何一个bash的会话。
2024-07-14 18:15:54
683
20
原创 网络基础知识
答案是可以的,它们可以直接通过Mac地址进行广播,对于不是发给自己的直接丢弃,是发给自己的就进行解包,但是局域网中通知只允许一台主机在局域网中发消息,如果多台主机同时进行发送消息,就会发生消息碰撞,这就是一个碰撞域,所以局域网本身就是一个临界资源,碰撞避免和检测重发就是进行互斥访问。TCP/IP是一组协议的代名词,它还包括许多协议,组成了TCP/IP协议簇.TCP/IP通讯协议采用了5层的层级结构,每一层都呼叫它的下一层所提供的网络来完成自己的需求。因为每个层之间的协议是不一样的,无法通信。
2024-07-01 23:03:29
1669
25
原创 生产者消费者模型
当然这个生产消费模型最重要的也是生产数据和消费数据两个接口,对于生产者来说,刚开始需要先申请信号量,然后生产数据,生产完之后需要归还消费者的信号量,因为生产了一个数据,就可以允许生产者进来消费一个了,对于生产者同理,但是不管是生产者还是消费者,它们的信号量都可能不是1,所以在生产数据和消费数据的过程中可能会存在多个执行流同时进入,所以在生产和消费的过程中还是需要加锁的。信号量的本质是一把计数器,当一个资源被分成多份,可以被多个线程共用的时候,就可以使用信号量。: 解耦、支持并发、支持忙闲不均。
2024-05-29 19:04:56
1005
27
原创 线程互斥和同步
比如说上面的抢票逻辑,假设没有票之后线程不退出还要接着抢票,工作人员会过一段时间放一批票进去,那么如果不用条件变量的话,没有票后,线程就会疯狂的申请锁和释放锁,会不断地消耗CPU资源,所以我们希望的是没票了你就在那等,工作人员放票之后通知你,你在抢,不通知你就一直在那等。这是因为我们在等待的时候,前提就是我们申请了一遍锁,然后访问临界资源不满足条件开始等待,这样就会面临锁在我自己这里,我自己被阻塞了,导致后面线程无法进来,所以需要把自己的锁传进去,这个函数会进行解锁操作,再醒来时,会自动重新申请锁资源。
2024-05-28 21:12:10
866
24
原创 C++中的类型转换
强制类型转换关闭或挂起了正常的类型检查,每次使用强制类型转换前,程序员应该仔细考虑是否还有其他不同的方法达到同一目的,如果非强制类型转换不可,则应限制强制转换值的作用域,以减少发生错误的机会。强烈建议:避免使用强制类型转换。static_cast用于非多态类型的转换(静态转换),编译器隐式执行的任何类型转换都可用static_cast,但它不能用于两个不相关的类型进行转换。因此C++提出了自己的类型转化风格,注意因为C++要兼容C语言,所以C++中还可以使用C语言的转化风格。
2024-05-24 23:55:33
557
24
原创 线程的概念和控制
我们使用的所有的线程的函数都不是系统直接提供的,是原生线程库提供的,而原生线程库一定不只会有我们一个进程用,所以原生线程库中一定会存在多个进程创建的多个线程,所以线程库一定要把我们多个进程创建的线程给管理好,所以线程库中会存在描述线程的结构体,结构体中有很多线程的数据(属于哪个进程,线程id等),然后再用数据结构把各个描述线程的结构体管理起来。对上提供线程控制的接口。因为线程是在进程的地址空间中运行的,并且线程创建更简单,只需要复制进程的PCB,只有一小部分的数据是私有的,大部分数据都和进程是一样的。
2024-05-23 22:41:46
1673
19
原创 进程信号 signal
如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。由于信号处理函数的代码是在用户空间的,处理过程比较复杂,举例如下: 用户程序注册了SIGQUIT信号的处理函数sighandler。当前正在执行main函数,这时发生中断或异常切换到内核态。在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。
2024-05-15 23:11:59
1155
31
原创 【进程间通信】共享内存
共享内存的通信方式,不会提供同步机制,共享内存是直接裸露给所有的使用者的,所以一定要注意共享内存的使用安全问题。共享内存可以提供较大的空间。共享内存是所有进程间通信中速度最快的。可以减少数据拷贝的次数。为什么说共享内存是最快的?这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据,也就会减少很多的数据的拷贝。
2024-05-08 23:32:56
1246
39
原创 【进程间通信】管道和命名管道
一个文件被打开了两次,因为他们打开的方式不一样,所以他们的标记为也一定不一样,它们在内存中的file结构体一定是存在两份的,但是文件的属性和操作集合都是一样的,所以文件属性和操作集合以及文件缓冲区是存在一份的,每个file结构体中会有一些基本的属性(读写位置等等),其次还会有一些指针,分别指向自己的属性和方法集合以及缓冲区。我们可以看到fd数字是一个文件描述符数组,所以Linux管道是复用了很多文件部分的代码的,所以在通信的时候很多还是文件的操作。管道是Unix中最古老的进程间通信的形式。
2024-05-04 18:36:35
1383
43
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人