当前位置: 首页 > news >正文

重写muduo之TcpServer

目录

1、Callbacks.h

2、TcpServer.h

3、TcpServer.cc


1、Callbacks.h

回调操作

#pragma once#include <memory>
#include <functional>class Buffer;
class TcpConnection;using TcpConnectionPtr=std::shared_ptr<TcpConnection>;
using ConnectionCallback=std::function<void(const TcpConnectionPtr&)>;
using CloseCallback=std::function<void(const TcpConnectionPtr&)>;
using WriteCompleteCallback=std::function<void(const TcpConnectionPtr&)>;
using MessageCallback=std::function<void(const TcpConnectionPtr&,Buffer*,Timestamp)>;

2、TcpServer.h

#pragma once/*** 用户使用muduo编写服务器程序* 在这里加上头文件,用户使用的时候就不用加了
*/
#include "EventLoop.h"
#include "Acceptor.h"
#include "InetAddress.h"
#include "noncopyable.h"
#include "EventLoopThreadPool.h"
#include "Callbacks.h"#include <functional>
#include <string>
#include <memory>
#include <atomic>
#include <unordered_map>//对外的服务器编程使用的类
class TcpServer:noncopyable
{
public:using ThreadInitCallback=std::function<void(EventLoop*)>;enum Option//预制两个选项来表示端口是否可重用{kNoReusePort,//不可重用kReusePort,//可重用};TcpServer(EventLoop* loop,const InetAddress& listenAddr,const std::string& nameArg,Option option=kNoReusePort);~TcpServer();void setThreadInitcallback(const ThreadInitCallback& cb){threadInitCallback_=cb;}void setConnectionCallback(const ConnectionCallback& cb){connectionCallback_=cb;}void setMessageCallback(const MessageCallback& cb){messageCallback_=cb;}void setWriteCompleteCallback(const WriteCompleteCallback& cb){writeCompleteCallback_=cb;}//设置底层subloop的个数void setThreadNum(int numThreads);//开启服务器监听void start();
private:void newConnection(int sockfd,const InetAddress& peerAddr);void removeConnection(const TcpConnectionPtr& conn);void removeConnectionInLoop(const TcpConnectionPtr& conn);using ConnectionMap=std::unordered_map<std::string,TcpConnectionPtr>;EventLoop* loop_;//baseloop 用户定义的loopconst std::string ipPort_;//保存服务器相关的ip地址,端口号const std::string name_;//保存服务器名称std::unique_ptr<Acceptor> acceptor_;//运行在mainloop,任务就是监听新连接事件std::shared_ptr<EventLoopThreadPool> threadPool_;//one loop per threadConnectionCallback connectionCallback_;//有新连接时的回调MessageCallback messageCallback_;//有读写消息时的回调WriteCompleteCallback writeCompleteCallback_;//消息发送完成以后的回调ThreadInitCallback threadInitCallback_;//loop线程初始化的回调std::atomic_int started_;int nextConnId_;ConnectionMap connections_;//保存所有的连接
};

3、TcpServer.cc

mainLoop相当于reactor模型的reactor反应堆的角色
poller相当于是多路分发器的角色,掌控epoll的所有操作

Acceptor创建listenfd,封装成acceptchannel,通过enableReading向poller上注册读事件,并将listenfd添加到poller中,poller监听acceptChannel上的事件,有事件发生时执行一个读事件的回调(因为之前约定的是对读事件感兴趣),读事件的回调绑定的是handleRead,handleRead中accept函数返回一个跟客户端通信的connfd,然后去执行相应的回调

IOLoop运行在主线程中,想要把当前connfd封装的channel发送给subloop1,但是subloop1还没有被唤醒,我是在主线程中操作IOLoop的,很明显IOLoop和subLoop1不在一个线程,所以执行queueinloop唤醒subloop1,相当于在subloop1中的wakeupfd中写了一个数字,然后就把这个新的TcpConnection注册到subloop1中,操作到其它subloop上也是一样的过程。

重写代码:

#include "TcpServer.h"
#include "Logger.h"EventLoop* CheckLoopNotNull(EventLoop* loop)
{if(loop==nullptr){LOG_FATAL("%s:%s:%d mainLoop is null!\n",__FILE__,__FUNCTION__,__LINE__);}return loop;
}TcpServer::TcpServer(EventLoop *loop,const InetAddress &listenAddr,const std::string &nameArg,Option option):loop_(CheckLoopNotNull(loop)),ipPort_(listenAddr.toIpPort()),name_(nameArg),acceptor_(new Acceptor(loop,listenAddr,option==kReusePort)),threadPool_(new EventLoopThreadPool(loop,name_)),connectionCallback_(),messageCallback_(),nextConnId_(1)
{//当有用户连接时,会执行TcpServer::newConnection回调    acceptor_->setNewConnectionCallback(std::bind(&TcpServer::newConnection,this,std::placeholders::_1,std::placeholders::_2));
}TcpServer::~TcpServer()
{}// 设置底层subloop的个数
void TcpServer::setThreadNum(int numThreads)
{threadPool_->setThreadNum(numThreads);
}// 开启服务器监听   loop.loop()
void TcpServer::start()
{if(started_++==0)//防止一个TcpServer对象被start多次{threadPool_->start(threadInitCallback_);//启动底层的loop线程池loop_->runInLoop(std::bind(&Acceptor::listen,acceptor_.get()));}
}// void TcpServer::newConnection(int sockfd, const InetAddress &peerAddr);
// void TcpServer::removeConnection(const TcpConnectionPtr &conn);
// void TcpServer::removeConnectionInLoop(const TcpConnectionPtr &conn);

相关文章:

重写muduo之TcpServer

目录 1、Callbacks.h 2、TcpServer.h 3、TcpServer.cc 1、Callbacks.h 回调操作 #pragma once#include <memory> #include <functional>class Buffer; class TcpConnection;using TcpConnectionPtrstd::shared_ptr<TcpConnection>; using ConnectionCall…...

腾讯云服务器之ssh远程连接登录及转发映射端口实现内网穿透(实现服务器访问本地电脑端口)

目录 一、创建密钥绑定实例二、设置私钥权限三、ssh远程连接到服务器四、修改root密码五、端口转发&#xff08;实现服务器访问本地电脑的端口&#xff09; 一、创建密钥绑定实例 创建密钥会自动下载一个私钥&#xff0c;把这个私钥复制到c盘 二、设置私钥权限 1、删除所有用户…...

oracle 9i 行头带有scn的表

oracle 9i 行头带有scn的表 conn scott/tiger drop table t1; drop table t2; create table t1(c varchar2(5)); create table t2(c varchar2(6)) ROWDEPENDENCIES; --t2表每行都有scn,会增加六个字节的开销 alter table t1 pctfree 0; alter table t2 pctfree 0; insert in…...

MySql#MySql安装和配置

目录 一、卸载不需要的环境 二、安装mysql yum 源 三、开始安装 四、如果保证安装成功呢&#xff1f; 五、MySql 启动&#xff01; 六、登录mysql 七、配置文件说明 八、设置开机启动&#xff01; 本次安装是在Linux环境在centos7中完成 首先先将自己切换成root 一、…...

WEB前端复习——HTML

固定格式&#xff1a;开头<!DOCTYPE html> <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>标…...

Java医院绩效管理应用系统源码java+ maven+ avue 公立医院绩效考核管理系统源码 支持二开

Java医院绩效管理应用系统源码java maven avue 公立医院绩效考核管理系统源码 支持二开 医院绩效管理系统解决方案紧扣新医改形势下医院绩效管理的要求&#xff0c;以“工作量为基础的考核方案”为核心思想&#xff0c;结合患者满意度、服务质量、技术难度、工作效率、医德医风…...

湖南知识付费系统开发公司,教育机构如何提高转化率?有哪些途径?

教育行业必须线上线下一起抓。当下教育机构不得不考虑线上招生、线上教学和服务。但是大多数人&#xff1a;没思路、没人才&#xff0c;不知道如何下手?其实线上运营也没那么难&#xff0c;“危机”即“机遇”。教育机构如何提高转化率&#xff1f;有哪些途径&#xff1f; 一、…...

Goland GC

Goland GC 引用Go 1.3 mark and sweep 标记法Go 1.5 三色标记法屏障机制插入屏障删除写屏障总结 Go 1.8 混合写屏障(hybrid write barrier)机制总结 引用 https://zhuanlan.zhihu.com/p/675127867 Garbage Collection&#xff0c;缩写为GC&#xff0c;一种内存管理回收的机制…...

【SRC实战】合成类小游戏外挂漏洞

挖个洞先 https://mp.weixin.qq.com/s/ZnaRn222xJU0MQxWoRaiJg “以下漏洞均为实验靶场&#xff0c;如有雷同&#xff0c;纯属巧合” 合成类小游戏三个特点&#xff1a; 1、一关比一关难&#xff0c;可以参考“羊了个羊” 2、无限关卡无限奖励&#xff0c;可以参考“消灭星星…...

【牛客】SQL206 获取每个部门中当前员工薪水最高的相关信息

1、描述 有一个员工表dept_emp简况如下&#xff1a; 有一个薪水表salaries简况如下&#xff1a; 获取每个部门中当前员工薪水最高的相关信息&#xff0c;给出dept_no, emp_no以及其对应的salary&#xff0c;按照部门编号dept_no升序排列&#xff0c;以上例子输出如下: 2、题目…...

2024年最新趋势跨境电商平台开发需了解的新技术

随着数字化技术的不断演进和全球市场的日益融合&#xff0c;跨境电商平台开发将面临前所未有的挑战和机遇。为了更好地适应并引领这一发展&#xff0c;开发者需要密切关注2024年最新的技术趋势&#xff0c;以确保他们的平台能够在竞争激烈的市场中脱颖而出。本文将对跨境电商平…...

Mac 查看jdk版本

$ /usr/libexec/java_home -VMatching Java Virtual Machines (1): 1.8.0_232 (x86_64) “AdoptOpenJDK” - “AdoptOpenJDK 8” /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home...

C++面向对象学习笔记五

本文主要讲解运算符重载&#xff0c;由于白鳯大佬没有具体讲解&#xff0c;所以本文自行补充了运算符重载的相关知识 目录 文章目录 前言 运算符重载 加号运算符重载 左移运算符重载 递增运算符重载 总结 前言 本文主要对于运算符重载进行探讨&#xff0c;分别对于成员函数重…...

7-Zip 的使用技巧

7-Zip 是一款功能强大的压缩软件&#xff0c;它提供了多种使用技巧来帮助用户更高效地管理文件。以下是一些7-Zip的使用技巧&#xff1a; 1. 压缩文件&#xff1a;用户可以通过7-Zip将文件或文件夹压缩成.7z或其他支持的格式&#xff0c;以节省空间。 2. 解压文件&#xff1a…...

德国储能项目锂电池储能集装箱突发火灾:安全挑战再引关注

2024年4月27日&#xff0c;德国尼尔莫尔商业区的一起锂电池储能集装箱火灾事件引起了全球关注。这起事故不仅导致两名消防员在救援过程中受伤&#xff0c;更暴露了储能系统在安全领域亟待解决的重要问题。 根据德国消防队的出警记录&#xff0c;火灾发生在晚上9点前不久。消防人…...

FFmpeg常用API与示例(二)—— 解封装与转封装

封装层 封装格式(container format)可以看作是编码流(音频流、视频流等)数据的一层外壳&#xff0c;将编码后的数据存储于此封装格式的文件之内。 封装又称容器&#xff0c;容器的称法更为形象&#xff0c;所谓容器&#xff0c;就是存放内容的器具&#xff0c;饮料是内容&…...

笨方法自学python(一)

我觉得python和c语言有很多相似之处&#xff0c;如果有c语言基础的话学习python也不是很难。这一系列主要是学习例题来学习python&#xff1b;我用的python版本是3.12 代码编辑器我用的是notepad&#xff0c;运行py程序用cmd 现在开始写第一个程序&#xff1a; print ("…...

centos7.9升级4.19内核

centos默认的内核版本是3.10 通过命令 uname -a 输出系统的详细信息 在部署k8s集群时使用默认的3.10版本的内核&#xff0c;容易出各种奇奇怪怪的问题、可以理解为docker和k8s与该内核版本不兼容&#xff0c;所以在部署k8s集群时&#xff0c;务必要升级内核&#xff0c;这里…...

神经网络模型与前向传播函数

1.概念 在神经网络中&#xff0c;模型和前向传播函数是紧密相关的概念。模型定义了网络的结构&#xff0c;而前向传播函数描述了数据通过网络的流动方式。以下是这两个概念的详细解释&#xff1a; 1.1 神经网络模型 神经网络模型是指构成神经网络的层、权重、偏置和连接的集…...

跟我学C++中级篇——内联补遗

一、内联引出的问题 在将一个内联变量定义到编译单元时&#xff0c;然后再按正常的方式使用时&#xff0c;编译会报一个错误“odr-used”。ODR&#xff0c;One Definition Rule&#xff0c;单一定义规则。在C/C程序中&#xff0c;变量的定义只能有一处&#xff0c;至于ODR的规…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

【从零学习JVM|第三篇】类的生命周期(高频面试题)

前言&#xff1a; 在Java编程中&#xff0c;类的生命周期是指类从被加载到内存中开始&#xff0c;到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期&#xff0c;让读者对此有深刻印象。 目录 ​…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...

Java求职者面试指南:Spring、Spring Boot、Spring MVC与MyBatis技术解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、Spring MVC与MyBatis技术解析 一、第一轮基础概念问题 1. Spring框架的核心容器是什么&#xff1f;它的作用是什么&#xff1f; Spring框架的核心容器是IoC&#xff08;控制反转&#xff09;容器。它的主要作用是管理对…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...

UE5 音效系统

一.音效管理 音乐一般都是WAV,创建一个背景音乐类SoudClass,一个音效类SoundClass。所有的音乐都分为这两个类。再创建一个总音乐类&#xff0c;将上述两个作为它的子类。 接着我们创建一个音乐混合类SoundMix&#xff0c;将上述三个类翻入其中&#xff0c;通过它管理每个音乐…...