
C++
文章平均质量分 78
以C++学习笔记为主
为了前进而后退,为了走直路而走弯路
https://darling-123456.github.io/个人博客网站,欢迎访问
展开
-
C++ 中 lower_bound 与 upper_bound 函数详解
关键区别检查元素是否存在结合 的返回值与目标值比较:统计元素出现次数使用 计算区间跨度:自定义排序规则支持传入比较函数,处理复杂数据结构或非默认排序:插入元素保持有序性在有序容器中插入新元素时,确定插入位置四、注意事项与常见误区必须保证序列有序迭代器越界检查自定义比较函数的一致性等价元素的处理差异若需获取所有等价元素的范围,建议使用equal_range(返回lower_bound和upper_bound的 pair 结果)六、总结 和 是处理有序序列的核原创 2025-05-09 13:15:04 · 1201 阅读 · 0 评论 -
关于C++使用lambda表达式写递归函数时的踩坑记录
引用捕获的方案通过类型擦除和延迟绑定,使得 Lambda 能间接调用自身,解决了递归问题。该方法的代价是性能开销,但在旧版 C++ 标准(C++11/14)中是常用方案若使用 C++17 或更高版本,优先选择显式对象参数语法,兼顾效率与简洁性。原创 2025-04-17 11:33:55 · 748 阅读 · 0 评论 -
C++集群聊天服务器项目博客目录
【代码】C++集群聊天服务器项目博客目录。原创 2025-02-18 15:46:20 · 726 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 项目管理以及github托管
如果你看到 “access denied” ,者表示拒绝访问,那么你就需要使用 https 去访问,而不是 SSH。这两个命令就是检查是否已经存在 id_rsa.pub 或 id_dsa.pub 文件,如果文件已经存在,那么你可以跳过步骤2,直接进入步骤3。当你看到上面这段代码的收,那就说明,你的 SSH key 已经创建成功,你只需要添加到github的SSH key上就可以了。接着又会提示你输入两次密码(该密码是你push文件的时候要输入的密码,而不是github管理者的密码),原创 2025-02-18 15:41:37 · 839 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 服务器集群
一台机器的文件描述符是有限的,之前的linux系统最大也就1024,那说明也就同时最多可以提供1024个人的服务聊天服务还是长连接,需要一直保持和服务器的连接才行,那么随着用户规模的扩大,就需要更多的服务器,而负载均衡器就是负责把这些请求分发到不同的服务器上面去。这样的设计使得各个服务器之间耦合度太高,不利于系统扩展,并且会占用系统大量的socket资源,各服务器之间的带宽压力很大,不能够节省资源给更多的客户端提供服务,因此绝对不是一个好的设计。负载均衡器有基于客户端的负载均衡和服务器的负载均衡。原创 2025-02-18 15:40:39 · 1196 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 客户端好友功能、群组功能开发以及退出功能实现
2.好友功能相关实现chat函数时遇到的问题:json解析时出现问题,本来应该接收到一个int结果却是null是因为发送方和接受方的json格式没有对应聊天业务中发送方的json中是to,而接收方json中是toid,导致出现解析问题3.群组功能相关4.注销功能加入了全局变量isMainMenuRunning表示用户是否在线,退出登录后就变为false,在线就是trueChatService.cpp记得要先绑定5.完整的客户端代码6.新增1.加入了全局变量isMainMenuRunni原创 2025-02-17 15:35:40 · 495 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 客户端首页功能开发
好友列表和离线消息表一般都是存储在本地,否则从服务器请求数据太多,但本项目采取从服务器拉取这两表。原创 2025-02-17 12:56:37 · 252 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 群组功能业务
实现三个功能:1.创建群2.加入群3.群里聊天。原创 2025-02-06 16:56:17 · 283 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 添加好友业务
添加好友后,每次用户登录会返回离线消息和好友列表这里的添加好友功能就是单方面的,我只要通过你的id加上你,就是加上了,不用同意或者拒绝。原创 2025-02-01 12:24:01 · 431 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 服务器异常退出
本次主要处理服务器程序因为ctrl+c退出的异常,会将所有online的改为offline。原创 2025-01-22 18:02:38 · 230 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 点对点聊天业务 && 离线消息存储业务
至此测试完成,但是这只是点对点的聊天业务,扩展到集群时还需要再添加相关代码的。因为不止可以在一台主机上登录,用户可以在别的主机上登录。业务逻辑:用户给用户发消息,如果目的用户在线,那就找到对应的连接,然后发送消息即可。如果目的用户不在线,那就存到离线消息表,等到下次上线的时候服务器再发过去。我们专门在offlineMessage表中存储离线消息业务的。1.张三登录,给未登录的李四发送消息。3.李四登录,有离线消息发过来了。2.查看离线消息表,确实有记录。4.数据库中的记录被删除。原创 2025-01-22 18:01:53 · 513 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 客户端异常退出业务
1.从map中删除用户的连接信息,因为要把底层的socket资源释放掉。2.更新用户状态信息 user表中状态改为offline。异常退出后状态变为offline。在登录后,状态变为online。启动Chatserver后。在另一个终端输入以下内容。原创 2025-01-22 18:00:55 · 230 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 用户登录业务 && 记录用户的连接信息以及线程安全问题
所以chatServer是一个长连接的服务器,只要用户登录着,那这个Tcp连接就会保持着。如果A和B用户发送消息,而服务器不知道A用户的连接的话就无法确切的把B的消息发给A。加的内容都是为了保证_userConnMap的线程安全操作。json都是局部变量,线程的栈是自己的,所以不需要线程安全。加入了记录用户连接的userConnMap。一个用户登录后服务器要记录用户的连接信息。没查询到就返回默认结果(id==-1)2.id==-1表示没有这个用户。为什么要记录用户的连接信息?原创 2025-01-22 18:00:04 · 1115 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | Model数据层代码框架设计 && 用户注册代码
数据库代码要和业务层分离开我们希望在业务层看到的都是对象在数据层操作具体的sql语句。原创 2025-01-22 17:59:18 · 453 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | MYSQL数据库代码封装
数据层和业务层也要解耦合,就像网络层和业务层一样业务层不要出现任何的mysql的增删改查要在业务层和数据层中间加入一层中间层,完成对sql语句的封装对于业务层要看到的直接操作对象,而不是sql语句数据层封装了数据库所有的操作。原创 2025-01-22 17:58:09 · 233 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 业务模块
通过js[“msgid”]绑定一个回调函数,对应获得一个业务处理器handler(handler就是回调函数)只要解析出来msgid就可以回调对应的函数,而不用写什么if(msgid==1)就怎么样怎么样这样的代码。原创 2025-01-22 17:57:31 · 523 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 网络模块
根据muduo网络库实现的,主要处理连接事件和读写事件。具体实现ChatServer。原创 2025-01-22 17:56:41 · 332 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | 工程目录创建
6.-thridparty第三方库的源码文件直接把第三方库的源码拿了过来集成到了自己的项目中。4.-build编译过程中产生的临时文件。8.-autobuild.sh一键编译。1.-bin生成的最终的可执行文件。 server存放服务器端用到的。 server存放服务器端用到的。 client存放客户端用到的。 client存放客户端用到的。5.-test示例代码测试文件。2.-include头文件。3.-src源代码文件。原创 2025-01-18 13:52:59 · 301 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | Mysql
修改属性的字符编码:altertableusermodifycolumnnamevarchar(50)charactersetutf8;ubuntu默认安装最新的mysql,但是初始的用户名和密码是自动生成的,按下面步骤修改mysql的root用。修改表的字符编码:altertableuserdefaultcharactersetutf8;这里用UserModel示例,通过UserModel如何对业务层封装底层数据库的操作。户密码为123456。原创 2025-01-18 13:51:38 · 478 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | CMake
使用简单方便,可以跨平台,构建项目编译环境。尤其比直接写Makefile简单(在构建大型工程编译时,需要写大量的文件依赖关系),可以通过简单的CMake生成负责的Makefile文件。就是使用一下CMake,编译一下我们的测试文件muduo_server.cppPROJECT_NAME:通过project()指定项目名称PROJECT_SOURCE_DIR:工程的根目录PROJECT_BINARY_DIR:执行cmake命令的目录。原创 2025-01-18 13:50:26 · 751 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | moduo网络库
建议大家打开muduo的源码,从TcpServer的start方法开始,阅读一下muduo库的源码实现,理解mainReactor和subReactor的工作原理,这样对于该项目的面试问题,也能更深入的去表达muduo相关的内容。一个BaseIOthread负责accept新的连接,接收到新的连接以后,使用轮询的方式在reactorpool中找。muduo网络库的编程很容易,要实现基于muduo网络库的服务器和客户端程序,只需要简单的组合。多个连接可能被分派到多个线程中,以充分利用CPU。原创 2025-01-18 13:49:40 · 1289 阅读 · 0 评论 -
C++项目 | 集群聊天服务器 | Json
Json是一种轻量级的数据交换格式(也叫数据序列化方式)。Json采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得Json成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。我们知道TCP是字节流,所以我们需要把发送的消息数据给序列化,用的工具就是Json。发送到对端再反序列化还原数据。intage;//将自定义数据类型转换为JSONjsonj=p;//从JSON转换为自定义数据类型。原创 2025-01-18 13:48:53 · 702 阅读 · 0 评论 -
C++集群聊天服务器项目总概述
掌握服务器中间件的应用场景和基于发布-订阅的redis编程实践以及应用原理。掌握服务器的网络I/O模块,业务模块,数据模块分层的设计思想。基于发布-订阅的服务器中间件redis消息队列编程实践。windows+vscode配置远程linux开发环境。掌握nginx配置部署tcp负载均衡器的应用以及原理。掌握C++muduo网络库的编程以及实现原理。安装boost+muduo网络库开发环境。nginx的tcp负载均衡器配置。linux系统运行sshd服务。配置远程linux主机的信息。原创 2025-01-18 13:47:54 · 436 阅读 · 0 评论 -
Ubuntu环境下安装部署Nginx
本文档适用于在Ubuntu24.04系统下部署nginx。原创 2025-01-18 13:44:41 · 1684 阅读 · 0 评论 -
ubuntu安装Redis
默认情况下,redis的配置文件在/etc/redis/redis.conf,打开这个文件,注释掉下面的内容。根据以上步骤安装启动redis后,默认只能在虚拟机内访问redis,如果在其他机器上访问,需要修改配置文件。在终端输入redis-cli,会进入到redis的命令行模式,这时候就可以愉快地使用redis的各种命令了。表明当前安装的Redis版本为6.0.16。在Ubuntu中,可以直接使用apt。原创 2025-01-18 13:43:49 · 413 阅读 · 0 评论 -
ubuntu安装MySQL
会在安装过程中,系统将提示你设置MySQL的root密码。确保密码足够强,且记住它,因为你将在以后需要用到它。在进行任何软件安装之前,请确保你的系统的软件包列表是最新的。默认安装是没有设置密码的,需要我们自己设置密码。至此,你已经成功在线安装了MySQL服务器。原创 2025-01-18 13:43:03 · 173 阅读 · 0 评论 -
windows下使用vscode远程连接Linux服务器进行开发
vscode推出了RemoteDevelopment开发包,让我可以在不同的场景快速切换,无需等待同步文件、环境。因为vscode远程开发完全是运行在服务器上的,我们本地的vsocde只是一个前端界面,所以根本无需同步服务器上的文件、解释器依赖库就可以体验到与本地开发完全相同的体验。原创 2025-01-18 13:42:14 · 1045 阅读 · 0 评论 -
基于C++11线程池项目博客目录汇总
线程池 | C++ | 项目实战-优快云博客线程池 | Any、Semaphore类-优快云博客线程池 | Result、Task类-优快云博客线程池 | ThreadPool的submitTask和threadFunc方法-优快云博客线程池 | Thread、ThreadPool类-优快云博客线程池 | 测试代码-优快云博客线程池 | Linux平台编译线程池动态库-优快云博客基于C++14和C++17的改进版本:packaged_task 、future知识点-优快云博客线程池 | 改进原创 2025-01-16 18:18:21 · 826 阅读 · 0 评论 -
线程池 | 改进版
重难点:可变参模板编程,future和packaged_task的使用,bind和function的理解。主要改动的就是submitTask函数,threadFunc少量改动,其他的函数没有改动。使用future代替Result,future等价于咱们自己写的Result。直接传入函数作为线程函数,后面是该函数的参数作为任务给到线程池。2.Result以及相关的类型都是自己写的,其实都是有现成的。省略掉用户自己创建myTask类和重写run方法的这个过程。1.如何能让用户提交任务的过程更加简单方便?原创 2025-01-16 18:15:21 · 341 阅读 · 0 评论 -
packaged_task 、future知识点
是一个任务包装器,将可调用对象和future关联,可在另一个线程中执行任务并存储结果。可通过获取关联的future对象。future用于获取异步操作的结果,调用get()会阻塞线程,直到结果可用。可处理异常,存储关联任务抛出的异常并在get()时重新抛出。和future是 C++ 中进行异步编程和任务管理的重要工具,它们使你能够方便地在不同线程中执行任务并获取结果,同时处理异常,实现并发和并行计算。原创 2025-01-16 18:14:04 · 704 阅读 · 0 评论 -
线程池 | Linux平台编译线程池动态库
环境:ubuntu24.04。原创 2025-01-16 16:07:28 · 171 阅读 · 0 评论 -
线程池 | 测试代码
【代码】线程池 | 测试代码。原创 2025-01-16 15:04:52 · 193 阅读 · 1 评论 -
线程池 | Thread、ThreadPool类
////////////////线程池类的方法实现//最多支持多少任务//最多支持多少线程//最长空闲时间,超过就要回收单位是秒数量少是因为测试方便,大家可以自行修改。原创 2025-01-16 15:02:50 · 442 阅读 · 0 评论 -
线程池 | ThreadPool的submitTask和threadFunc方法
1.submitTask()1.获取锁提交任务涉及入队操作,对任务队列进行操作必须是线程安全的,所以要先获取锁 会在其生命周期结束时自动释放锁,防止忘记解锁而导致死锁2.等待任务队列有空余空间:使用条件变量 来等待任务队列 有空余空间。 函数会等待最多 1 秒钟,在等待期间会释放 锁,以便其他线程可以添加或移除任务。等待的条件是任务队列的大小小于 ,如果条件满足或者等待超时(1 秒),函数将继续执行。如果等待超时且条件不满足,函数将输出错误信息并返回一个表示失败的 对象。3.将原创 2025-01-16 15:02:04 · 946 阅读 · 0 评论 -
线程池 | Result、Task类
这个类用来接收对应task_任务结束后的返回值的,一个Task对象对应一个Result对象,Any对象作为类内成员承接具体的返回值。setVal方法是把返回值存储到Result对象的any上,get方法是用户获取task返回值的方法,就是把any的值返回给用户。值得注意的是,加入了信号量来控制是否完成了任务,如果任务没有完成,会在get方法处阻塞,等待任务完成。使用时,用户自己定义一个mytask类继承Task类,重写run方法完成自己想要的任务即可。这两者是耦合的,一个Task对应一个Result。原创 2025-01-16 14:31:26 · 241 阅读 · 0 评论 -
线程池 | Any、Semaphore类
模板允许Any类接受任何类型的数据,因为对于不同类型的数据,会生成相应的Derive<T>实例。多态允许将这些不同类型的Derive<T>实例存储在base_指针中,因为它们都继承自Base。cast_方法使用进行运行时类型检查,以确保提取的数据类型与存储的数据类型匹配。原创 2025-01-16 14:18:29 · 619 阅读 · 0 评论 -
线程池 | C++ | 项目实战
作为五大池之一(内存池、连接池、线程池、进程池、协程池),线程池的应用非常广泛,不管是客户端程序,还是后台服务程序,都是提高业务处理能力的必备模块。有很多开源的线程池实现,虽然各自接口使用上稍有区别,但是其核心实现原理都是基本相同的。原创 2025-01-16 13:27:00 · 882 阅读 · 0 评论 -
Effective C++读书笔记博客汇总
做过两个项目以后,第二次读才写的博客,有一些地方确实在项目中会运用到,但其他的还是有不少不太理解的,之后再做做别的项目进行第三次阅读之后再进行补充。我是第一次读到一半就没读了,觉得看不懂,读起来也比较枯燥。原创 2024-10-28 19:48:39 · 633 阅读 · 0 评论 -
Effective C++ | 读书笔记 (三)
提前定义变量,有可能导致变量并没有使用(如中间抛异常了),而平白多了一个构造和析构成本。但是循环怎么办?// 方式AWidget w;i < n;...// 方式Bi < n;++i) {...做法A:1个构造 + 1个析构 + n个赋值操作做法B:n个构造函数 + n个析构函数打破本条款选择A的依据:(1)你知道赋值成本比“构造+析构"成本低。(2)你正在处理代码中效率高度敏感的部分。否则你应该使用做法B,维持变量尽可能在使用时定义的原则。请记住。原创 2024-10-28 19:42:11 · 841 阅读 · 0 评论 -
Effective C++ | 读书笔记 (四)
对应条款24,这里只是模版实现。规则一致,但它们写法上有所区别了。public:...// 需要隐式转换的接口定义为非成员函数{...};// 使用// 这里会编译错误,2不能隐式转换上面只是把24条款示例改为模版实现,然而模版版本是编译不过的,因为编译器并不知道2要转换为什么。编译器推断不了模版的隐式转换。对于模版我们只能通过friend和inline特性来实现非成员函数的定义。public:...// 这里Rational是Rational<T>的简写形式,在类模版内部可以简写。原创 2024-10-28 19:43:35 · 1010 阅读 · 0 评论