自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(41)
  • 收藏
  • 关注

原创 手写精简版TinyHttpd项目(一)

我们在之前的TinyHttpd的精读(可以在首页去查看)中已经是基本的了解了显示一个网页的基本过程,那么我们学习后可以通过手写一个精简版的进行巩固下。

2024-06-18 23:03:57 863

原创 手写精简版TinyHttpd项目(二)

在上一章中,我们基本完了socket通信的建立和消息的处理,那么这一章我们就来看如何生成一个静态的网页。

2024-06-18 23:03:52 289

原创 TinyHttpd源码精读(三)

当然后面的cgi这个算是一个精简版讲解,受限于cgi的布置,我们也不太容易一睹原项目中cgi的风采,但是思路是一样的。其中对于异常情况的处理和思路也是值得我们去学习的,不过我并不是主修web服务这块的,所以目前这块我的理解不够深入,暂时也不打算这样深入。主体的逻辑就是从pipe函数那里开始,创建一个子进程,父子进程的环境啥的都完全一样,然后再子进程里面打开cgi脚本,并且将脚本的输出通过dup2函数和cgi_output,cgi_input传递到父进程里面,然后由父进程传递到client(网页)中。

2024-06-11 22:19:16 403

原创 TinyHttpd源码精读(二)

书接上文,我们在TinyHttpd源码精读(一)中简单的讲解了项目的运行和main函数以及accept_request函数的主体内容。基本上这个项目的主线思路就差不多一半了,接下来我们看看这个项目是如何显示静态网页和动态的网页的。

2024-06-11 22:19:11 1077 1

原创 Socket通信学习(三):两个客户端通过服务端中转进行数据的传递

这块的思路不难,但是再后面的结果中我们发现虽然我们可以实现简单的对话但是只有当两个客户端都输入完成后才能显示出接受到的数据。当然这个可以采取两个线程,一个发送消息,一个去接受消息。同样的,对于客户端的链接我们其实也可以单独开一个线程去实时的去监听。这些具体的功能,我们后面再去慢慢的实现这个吧。

2024-06-05 00:28:24 576

原创 TinyHttpd源码精读(一)

本文章主要是记录自己对于TinyHttpd的源码的阅读理解。

2024-06-05 00:27:46 492

原创 Soket通信学习(二):服务端和客户端的简单的对话交流

上一篇我们已经能成功的创建服务端和客户端的代码并且能创建一个简单的沟通链接,既然能建立的话,我们就循环下这个发送和接受信息的过程即可,然后注意下清空接受信息的buffer数组。可以先自己动手修改下代码然后再看下面的代码。

2024-04-29 00:43:05 123

原创 Soket通信学习(一):创建服务端和客户端并建立简单的通信

这篇文章不详细说socket的基础理论直接聚焦代码方面的实操,毕竟刚刚开始学这个的时候还是得先上手后才能更好的去理解背后的原理和知识。一般的工作中也是要求先使用后去理解。(开发/编译环境:ubuntu )

2024-04-29 00:18:13 484

原创 回调函数浅聊

我们可以看到,作为参数来看可调用对象是非常多的,函数名称,lambda表达式,函数指针等,我们在编写回调函数的时候是不知道会传入什么参数进来的,这样在我们试图使用统一的方式保持,或传递一个可调用对象时,会非常的繁琐。std::async 通常会根据执行策略(指定为 std::launch::async 或 std::launch::deferred)来决定是否创建新线程执行任务。综上所述,std::thread 适合对线程进行精细控制,而 std::async 更适合用于异步任务的简单启动和结果获取。

2023-11-28 11:37:17 105

原创 QT_OpenGL学习之路-------第二节

在上一节中,我们介绍了如何入新建一个opengl的窗口,但是QT中的OpenGL的使用和OpenGL本身的使用有些不一样,QT进行了一定的封装。从这里面我们可以知道:paintGL():渲染OpenGL窗口的函数,当窗口需要刷新的时候被调用,resizeGL():设置OpenGL的 viewport,第一次出现窗口或者窗口大小变化的时候被调用。initializeGL():设置OpenGL的资源和状态,只会在最开始的时候被调用一次,所以这个函数就是初始化的,最开始调用。

2023-11-28 11:36:36 135

原创 线程三----------异步操作

异步操作是一种执行任务而无需等待其完成的方式。异步操作可以提高程序的并发性和响应性,适用于需要长时间执行的任务或需要与外部资源进行交互的情况。C++中提供了异步操作相关的类,主要有:std::future,std::promise和std::package_task。其中std::future作为异步结果的传输通道,可以很方便地获取线程函数的返回值;std::promise用来包装一个值,将数据和future绑定起来,方便线程赋值;std::package_task用来包装一个可调用对象,

2023-11-22 23:37:15 101

原创 QT_OpenGL学习之路-------第一节(环境的搭建和窗口的渲染)

默认QT已经下载并且安装OK了,这里使用的是QT6.2。

2023-11-20 10:54:27 129

原创 Shell笔记第四节(函数,文件包含,重定向)

2.参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。return 后跟数值n(0-255)1.可以带function fun()定义,也可以直接fun()定义,不带任何参数。

2023-11-15 23:59:32 50

原创 Shell笔记第三节--(printf,test,流程控制,循环语句)

until循环执行一系列命令直到条件为ture时停止,until循环与while循环在处理方式上刚好相反。一般的while循环优于until循环,不过在某些情况下until循环更加好用。Shell中的test命令用于检查某个条件是否成立,它可以进行数组,字符和文件三方面的测试。%-10s指一个宽度为10个字符(-表示左对齐,没有则右对齐),不足使用空格进行填充。当condition的值为false的时候才会执行command,否则就跳出循环。其流程控制和C中的if类似,不过sh的流程控制不可为空。

2023-11-14 15:27:17 126

原创 Shell笔记第二节

我们在一些项目中需要向脚本输入一些参数,脚本内获取参数的格式为:$n。n代表一个数字,1为执行脚本的第一个参数,2为执行脚本的第二个参数,以此类推。再此进行一个初略的估计:应该是将输入都放在一个数组或者字符串中,再有脚本去读入,这样./shell1.sh才是第0个元素。如“$@”用["]括起来的情况,以"$1" "$2" ... "$n"的形式输出所有参数。如“$*”用["]括起来的情况,以“$1 $2 ... $n”的形式输出所有参数。与$*相同,但是使用时加引号,并在引号中返回每个参数。

2023-11-14 11:12:18 33

原创 Shell笔记第一节

在Shell中,用括号来表示数组,数组元素用"空格"分开:数组名=(值1 值2 ... 值n) /数组名[n]=n/bin/bash输出结果:1,2,3,4771,2,3,4,77在Shell中数组可以不使用连续的下标,且下标的范围没有限制。输出数组的所有内容直接使用echo ${your_name[@]}

2023-11-13 16:05:28 35

原创 线程(二)

当我们的同步队列在没有满的情况下可以正常的插入数据,满了则会调用m_notFull.wait(m_mutex) 来阻塞进程进行等待,待消费线程取出数据后发一个未满的通知,然后前面阻塞的线程就会被唤醒继续往下执行。如果不满足条件则会释放mutex,然后将线程置为waiting状态,继续等待。C++11提供一个原子类型std::atomic<T>,可以使用任意类型作为模板参数,C++11内置了整型的原子变量,可以更加方便地使用原子变量,使用原子变量就不需要使用互斥量来保护该变量了。如果条件满足,则向下执行。

2023-11-10 16:31:27 32

原创 线程(一)

C++11中提供了std::thread来创建线程,其使用非常的简单,只需要提高线程函数或者函数对象即可,并且可以同时指定线程函数的参数。在上例中,函数thread_func_01()将会运行于线程对象t中,join函数将会阻塞线程,直到线程函数执行结束,如果线程函数有返回值,返回值将被忽略。输出的结果是:如果不希望线程被阻塞执行,可以调用线程的detach()方法,将线程和线程对象分离。通过detach,线程就和线程对象分离了,让线程作为后台线程去执行,当前线程也不会阻塞了。

2023-09-20 00:02:06 58

原创 基于范围的for循环

在C++98中,不同的数据和容器,遍历的方法不尽相同,写法也不同意,比较繁琐。在C++11中新增了一个基于范围的for循环以统一,简洁的方式来遍历容器和数组。在上述代码中,虽然有auto但是还是无法避免出现begin()和end()等繁琐的迭代器。从上述代码中可以看到for循环的代码写得非常的简洁,且输出的内容一致。在上面的基于范围的for循环中,n表示arr中的一个元素,auto则是让编译器自动推导出n的类型。

2023-09-13 23:11:41 55

原创 返回值类型后置

在泛型编程中,可能需要通过参数的运算来得到返回值的类型。

2023-09-12 23:09:38 81

原创 C++11中的智能指针

智能指针是存储指向动态分配(堆)对象指针的类,用于生存期的控制,能够确保在离开指针所在作用域时,自动的销毁动态分配的对象(和普通指针的区别防止内存泄露。智能指针分三种:1.std::shared_ptr:共享的智能指针,多个智能指针来同时管理这块内存。2.std::unique_ptr:独享的智能指针,只能有一个指针来管理,如果下一个指针也要管理,那么资源就会转移到下一个unique_ptr的智能指针上。

2023-09-11 23:49:46 85

原创 Decltype关键字

3.带括号的表达式和加法运算表达式(其他情况下,若exp是一个左值,则decltype(exp)是exp类型的左值引用,否则和exp类型一致。.表达式为普通变量或者普通表达式或者类表达式,在这种情况下,使用decltype推导出的类型和表达式的类型是一致的。推导是在编译期完成的,它只是用于表达式类型的推导(相较于auto,它可以进行复杂表达式的推导)。2.exp是函数调用,decltype(exp)和返回值的类型一致。decltype(exp),其中exp表示一个表达式(expression).

2023-08-28 21:34:24 186 1

原创 Auto的使用:

主要是简单明了的了解auto的概念和使用方法以及注意事项。

2023-08-24 22:59:49 113 1

原创 本文章将详细介绍Qt的绘图QPainter的使用

QPainter是用来进行绘图操作的类,QPainterDevice是一个可以使用QPainter进行绘图的抽象的二维界面,QPainterEngine给QPainter提供在不同设备上绘图的接口。Qt的二维绘图基本功能是使用QPainter在绘图设备上绘图,绘图设备包括QWidget,QPixmap等,通过绘制一些基本的点,线,圆等基本形状组成自己想要的图形,得到的图形是不可交互操作的图形。brush属性:QBrush 笔刷,设置一个区域的填充特性,可以设置填充颜色,填充方式,渐变特性等。

2022-11-04 23:13:06 1473 1

原创 Model/view 第二部分:QFileSystemModel的使用

目的:通过路径获取当前系统的结构并且使用TreeView显示出来,在TreeView中点击一个目录时,其目录的下层文件信息在listview和tableview中显示出来。QFileSystemModel提供了一个可用于访问本机文件系统的数据模型,其和视图组件QTreeView结合使用,可以用目录树的形式显示本机上的文件系统。ui建立:新建三个groupBox,在其内部放入Treeview,ListView,TableView。QDir::currentPath()用于获取当前应用程序的当前路径。

2022-10-30 22:59:19 503

原创 Model/view 第一部分:基础知识

所有的基于项数据(item data)的数据模型(Model)都是基于QAbstractItemModel类的,这个类定义了视图组件和代理存取数据的接口。为视图组件设置一个数据模型就可以实现视图组件和数据模型之间的关联,在视图组件上的修改将自动保持到关联的数据模型里,一个数据模型可以同时在多个视图组件里显示数据。QStandardItemModel 标准的基于项数据的数据模型类,每个项数据可以是任何数据类型。代理负责从数据模型获取。一个项可以有不同的角色的数据,用于不同的场合。

2022-10-30 22:22:57 136

原创 C++实现简易定时器

里面包含了计时器id,定时的时长,触发定时器开始的时间,执行的任务。这个地方需要注意下getTime函数,通过GetLocalTime来获取当前的时间,然后使用mktime函数来讲当前的时间点转化成秒数,最后将秒数。所以我们首要需要一个接口来添加定时器(AddTimerHandler),将定时的时间和所需要执行的任务添加进入;不停的循环主任务,当定时器的时间到了就执行子任务。注意这里的任务是通过函数指针来实现回调函数的功能(即通过函数指针来执行函数有一定的局限性,C++11标准中有更好的方法)

2022-10-11 22:22:32 5219

原创 函数模板与类模板

函数模板和类模板

2022-09-28 23:55:54 227

原创 单例的学习

当我们声明函数的时候我们就在疑惑返回值,声明一个对象是有地址的,这里的地址我们要求不能被改变,且类声明完就得有。在它的核心结构中只包含一个被称为单例的特殊类,通过单例模式可以保证系统中一个类只有一个实例并且该实例易于外界访问。但是类不完成是无法实例化的,所以我们需要一个函数去外部实例化一个对象,且这个函数是外部可访问的。如果希望在系统中某个类的对象只能存在一个,单例是最好的解决方案。做完上述工作后,我们在类外实例化下即可完成一个单例的创建。单例就是只能实例化一个对象,(真惨,对象都只能有一个)

2022-09-28 23:18:58 116

原创 Lambda表达式

lambda表达式是C++中新引入的匿名函数 ,接下来我们来看看它的结构:[capture list] (params list) mutable exception-> return type { function body } capture list:捕获外部变量列表 params list:形参列表 mutable指示符:用来说用是否可以修改捕获的变量 exception:异常设定 return type:返回类型 function body

2022-07-06 21:34:44 120

原创 聊聊C++的继承

c++中最重要的就是多态,然而在继承是实现多态的一个重要的行为。子类继承父类,就会讲父类中的所有数据,行为统统继承。继承通过:来表明。例如: class animal{}class dog :public animal{}我们知道,一个类有构造函数和析构函数。那么在继承的过程中,父类和子类的构造和析构的执行顺序是怎么样的呢?我们来看如下代码:class animal{public: animal() { cout ...

2022-06-08 23:26:13 180

原创 浅聊map容器

在进入map容器前先看看map容器内存放的值的类型:pairpair 类型(键值对)声明:pair<T1, T2> p1;声明并初始化:pair<T1, T2> p1(v1, v2);make_pair(v1, v2)以 v1 和 v2 值创建一个新 pair 对象,其元 素类型分别是 v1 和 v2 的类型也可以这么使用:auto pair = make_pair(v1, v2);OK,简单的聊完了pair类型,接下来我们就进入map容器Map容器:..

2022-05-18 23:53:45 323 2

原创 简述快速排序算法

概念:快速排序是一种二叉树结构的交换排序方法,设数组a中存放了n个数据元素,low为数组的低端下标,high为数组的高端下标,从数组的a中任取一个元素(通常去a[low]作为标准),调整数组a中各个元素的位置,使排在标准元素前面的元素的关键字均小于标准元素的关键字,排在标准元素后面的元素的关键字均大于或等于标准元素的关键字。这样一次排序后,标准元素前面的元素均小于标准元素,后面的元素均大于或等于标准元素。然后对标准元素的前后分别在使用同样的方法进行递归快速排序。递归算法的结束条件是high<=low,

2022-05-15 21:17:50 464

原创 直接插入排序

概念:顺序的把带排序的数据元素按其关键字值的大小插入到已经排序数据元素子集合的适当位置。子集合的数据元素个数从只有一个数据元素开始,逐次增大,当子集合大小最终和集合大小相同时,排序完毕。设待排序的n个数据元素存放在数组a中,初始时,子集合a[0]已经排好序,第一次循环准备把a[1]插入到已经排好序的子集合中。这时只需要比较a[0],a[1]即可。若a[0]<=a[1],则说明序列有序,否则将a[1]插入到a[0]的前面去。此时子集合的大小增大为2,第二次循环准备把数据元素a[2]插入到已经排好

2022-05-14 22:03:44 233

原创 UDP链接通信:

UDP通信不需要建立链接,直接通过ip地址和端口的绑定即可实现通信所以首先我们需要绑定一个端口号,这里我们绑定本地的端口号:这个是端口号udpsocket->localPort()port = udpsocket->localPort()udpsocket->bind(port)当我们不需要绑定时我们可以使用:udpsocket->abort();//解除绑定OK现在我们已经将端口绑定好了,接下来只需要读取数据并且显示出来就行。和TCP协议一样,当有消

2022-04-14 22:34:37 1054

原创 网络连接部分:服务器和客户端的部署代码

QTcpServer *tcpserver; QTcpSocket *tcpsocket;这两个类是必须的(对于服务器而言)。其中QTcpServer 主要用于服务器端建立网络“监听”“创建网络Socket”连接。一般监听网络连接需要ip地址+端口。当有新的客户端连接时,会发射newConnect()信号当客户端和服务器端的链接建立后就通过QTcpSocket 来传输数据。接下来我们来创建一个简单的客户端和服务器端的链接,文字发送的小程序。服务器端:大致可以分为四部分,par

2022-04-10 21:54:51 571

原创 Qt中如何获取Ip地址

获取本机的IP地址首先获取本地的主机名称,QString hostname = QHostInfo::localHostName();然后根据主机名称,来获取"IP地址"。QHostInfo hostinfo = QHostInfo::fromName(hostname);但是这里的IP地址不只是IP地址。是一个总信息的集合hostinfo中通过addresses()函数来直接获取地址列表:QList<QHostAddress> addList = hostinfo.addresses()

2022-04-05 22:34:11 8871 2

原创 Qt中如何主机上所有接口的网络列表

Qt中提供了一个函数:QList<QNetworkInterface>::allInterface().用于返回网络列表。若列表不为空,则获取列表内的元素QNetworkInterface进一步细分。QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();//获取网络列表。然后对于list,使用循环单独来获取list里面的每个元素QNetworkInterface:QNetworkInterface.

2022-03-31 22:58:11 432

原创 QT中的容器和迭代器

QT中的容器和C++中的容器是很类似的,就是前面加了一个Q。容器分为关联容器和顺序容器,分类的标志应该是按照数据的存储或者排列来。顺序容器:顾名思义是按顺序来的,常见的C++中有List,vector,stack,queue等。所以在QT中就是QList,QLinkedList,QVector,QStack和QQueue。Qlist:数组链表。提供下标缩影方式访问数据,和数组是一样的,也提供at()函数。 示例...

2021-11-14 15:27:47 1419

原创 QT使用按钮来控制窗口的打开和关闭

1.首先新建工程,然后在添加一个新函数比如window1.cpp文件暂时可以不用写。然后就是主窗口的代码部分直接贴出来:#include "mainwindow.h"#include "ui_mainwindow.h"#include<QPushButton>#include<QDebug>#include"window1.h"MainWindow::MainWindow(QWidget *parent) : QMainWind

2021-09-29 21:55:11 1654

QT-OpenGL学习之路-第二节(三角形的源代码)

QT-OpenGL学习之路-第二节(三角形的源代码)

2023-11-28

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除