# muduo
基于C++11的muduo网络库
作者:shenmingik
邮箱:2107810343@qq.com
时间:2021/1/26 22:17
开发环境:Ubuntu VS Code
编译器:g++
编程语言:C++
源码链接:
[微云链接](https://share.weiyun.com/TvmQb52d)
# 写在前面
## 项目编译问题
项目编译时基于cmake的,在源码链接中有CMakeLists.txt文件,下载完之后直接点击那个编译即可。
## 库安装的问题
在源码链接的`/lib`目录中有一个autobuild.sh文件,用`chmod +x autobuild.sh`命令给它加上执行权限之后,执行就可。
> 注:博主的是Ubuntu系统,其他系统可以进去把地址给改一下
## 项目测试代码
这里简单的写了一个回显服务器用于测试,在源码链接的`/example`目录下,大家可以下载自己测试一下。
## 关于压力测试
由于我这里基本就是重写了一下原来的muduo + 懒(不是主要原因)
所以
压力测试可以直接参考陈硕大神做的:
[muduo 与 libevent2 吞吐量对比](https://blog.csdn.net/Solstice/article/details/5864889)
[muduo 与 boost asio 吞吐量对比](https://blog.csdn.net/Solstice/article/details/5863411)
# 项目概述
这个项目呢,是将陈硕大神的muduo网络库源码中核心代码部分重新写了一遍,将原来依赖boost库的地方都替换成了C++ 11语法。算是博主对muduo网络库达成更好理解的一个产品吧。
## muduo网络库的reactor模型
在muduo网络库中,采用的是**reactor**模型,那么,什么是reactor模型呢?
> **Reactor:**
> 即非阻塞同步网络模型,可以理解为,向内核去注册一个感兴趣的事件,事件来了去通知你,你去处理
> **Proactor:**
> 即异步网络模型,可以理解为,向内核去注册一个感兴趣的事件及其处理handler,事件来了,内核去处理,完成之后告诉你
## muduo的设计
reactor模型在实际设计中大致是有以下几个部分:
- Event:事件
- Reactor: 反应堆
- Demultiplex:多路事件分发器
- EventHandler:事件处理器
在muduo中,其**调用关系**大致如下
- 将事件及其处理方法注册到reactor,reactor中存储了连接套接字connfd以及其感兴趣的事件event
- reactor向其所对应的demultiplex去注册相应的connfd+事件,启动反应堆
- 当demultiplex检测到connfd上有事件发生,就会返回相应事件
- reactor根据事件去调用eventhandler处理程序
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210214113852361.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoZW5taW5neHVlSVQ=,size_16,color_FFFFFF,t_70)
而上述的,是在一个reactor反应堆中所执行的大致流程,其在muduo代码中**包含关系**如下(椭圆圈起来的是类):
可以看到,EventLoop其实就是我们的reactor,其执行在一个Thread上,实现了one loop per thread的设计。
每个EventLoop中,我们可以看到有一个Poller和很多的Channel,Poller在上图调用关系中,其实就是demultiplex(多路事件分发器),而Channel对应的就是event(事件)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210214120009308.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoZW5taW5neHVlSVQ=,size_16,color_FFFFFF,t_70)
现在,我们大致明白了muduo每个reactor的设计,但是作为一个支持高并发的网络库,单线程 往往不是一个好的设计。
muduo采用了和Nginx相似的操作,有一个main reactor通过accept组件负责处理新的客户端连接,并将它们分派给各个sub reactor,每个sub reactor则是负责一个连接的读写等工作。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210214111718808.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoZW5taW5neHVlSVQ=,size_16,color_FFFFFF,t_70)
# muduo各个类
明白了muduo的细节之后,我们对muduo的剖析就更为容易。
## 辅助类
这个类别的类与网络实现没有太大关系,只是用来辅助网络库的实现了
### NonCopyable
这个类将拷贝和赋值构造函数给delete掉,提供了一个**不可拷贝**的基类
```cpp
NonCopyable(const NonCopyable &) = delete;
NonCopyable &operator=(const NonCopyable &) = delete;
```
### TimeStamp
这个类用于给网络库提供系统时间,我这里用的是`time(nullptr)`函数
```cpp
TimeStamp();
explicit TimeStamp(int64_t times);
//获取当前时间
static TimeStamp now();
//转换为字符串
string to_string();
```
### Logger
这个是日志类,采用的是饿汉式的单例模式,用于打印网络库运行过程中的日志信息,主要分为四个级别
- INFO: 正常的日志输出
- ERROR: 有错误的日志输出,但是程序还可以运行
- FATAL: 有错误的日志输出,程序不可运行,直接exit
- DEBUG: 用于调试得到错误信息
同时也往外提供了四个宏函数用于打印信息:`LOG_INFO、 LOG_ERROR、LOG_FATAL、LOG_DEBUG`,由于四个函数相似度较大,我这里就放出一个函数LOG_INFO
```cpp
#define LOG_INFO(logmsgFormat, ...) \
do \
{ \
Logger &logger = Logger::instance(); \
logger.set_log_level(EnLogLevel::INFO); \
char buf[BUFFER_SIZE] = {0}; \
snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \
logger.log(buf); \
} while (0)
```
我们可以看到,这里是对输入数据进行了处理然后调的logger的log函数进行打印。
```cpp
//获取唯一实例对象
static Logger &instance();
//设置日志级别
void set_log_level(EnLogLevel level);
//写日志
void log(string msg);
```
### Buffer
这个是muduo网络库中底层的数据缓冲类型,模仿java中netty的设计,其有一个prepend、read、write三个标志,划分了缓冲区的数据。
其中perpend-read之间是一个头部的标志位,read-write是可读数据,write-末尾是可写数据。
应用将数据写入到网络库的Buffer缓冲区,然后Buffer缓冲区再写到TCP的缓冲区,最后再发送。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210214125729501.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NoZW5taW5neHVlSVQ=,size_16,color_FFFFFF,t_70)
```cpp
数据:
vector<char> buffer_;
size_t read_index_;
size_t write_index_;
方法:
//返回可读的长度
size_t readable_bytes() ;
//返回可写的长度
size_t wirteable_bytes();
//返回头长度
size_t prependable_bytes();
//返回缓冲区中可读数据的起始地址
const char *peek();
//缓冲区readindex 偏移
void retrieve(size_t len);
//缓冲区复位
void retrieve_all();
//读取所有数据
string retrieve_all_asString();
//读取len长度数据
string retrieve_as_string(size_t len);
//保证缓冲区有这么长的可写空间
void ensure_writeable_bytes(size_t len);
//返回可写数据地址
char *begin_write();
//忘缓冲区中添加数据
void append(const char *data, size_t len);
//从fd中读取数据
ssize_t readfd(int fd, int *save_errno);
//通过fd发送数据
ssize_t writefd(int fd, int *save_errno);
private:
//返回缓冲区起始地址
char *begin();
//扩容函数
void makespace(size_t len);
```
## Reactor中类
这个类别中主要讲解reactor中要实现的类
### InetAddress
这个类封装了socket所要绑定的**ip地址**和**端口号**,比较简单
```cpp
string get_ip() const;
string get_ip
没有合适的资源?快使用搜索试试~ 我知道了~
基于C++11的muduo网络库.zip
共95个文件
hpp:18个
cpp:18个
o:17个
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 79 浏览量
2024-06-03
15:59:30
上传
评论
收藏 1.95MB ZIP 举报
温馨提示
基于C++11的muduo网络库 C++是一种广泛使用的编程语言,它是由Bjarne Stroustrup于1979年在新泽西州美利山贝尔实验室开始设计开发的。C++是C语言的扩展,旨在提供更强大的编程能力,包括面向对象编程和泛型编程的支持。C++支持数据封装、继承和多态等面向对象编程的特性和泛型编程的模板,以及丰富的标准库,提供了大量的数据结构和算法,极大地提高了开发效率。12 C++是一种静态类型的、编译式的、通用的、大小写敏感的编程语言,它综合了高级语言和低级语言的特点。C++的语法与C语言非常相似,但增加了许多面向对象编程的特性,如类、对象、封装、继承和多态等。这使得C++既保持了C语言的低级特性,如直接访问硬件的能力,又提供了高级语言的特性,如数据封装和代码重用。13 C++的应用领域非常广泛,包括但不限于教育、系统开发、游戏开发、嵌入式系统、工业和商业应用、科研和高性能计算等领域。在教育领域,C++因其结构化和面向对象的特性,常被选为计算机科学和工程专业的入门编程语言。在系统开发领域,C++因其高效性和灵活性,经常被作为开发语言。游戏开发领域中,C++由于其高效性和广泛应用,在开发高性能游戏和游戏引擎中扮演着重要角色。在嵌入式系统领域,C++的高效和灵活性使其成为理想选择。此外,C++还广泛应用于桌面应用、Web浏览器、操作系统、编译器、媒体应用程序、数据库引擎、医疗工程和机器人等领域。16 学习C++的关键是理解其核心概念和编程风格,而不是过于深入技术细节。C++支持多种编程风格,每种风格都能有效地保证运行时间效率和空间效率。因此,无论是初学者还是经验丰富的程序员,都可以通过C++来设计和实现新系统或维护旧系统。3
资源推荐
资源详情
资源评论
收起资源包目录
基于C++11的muduo网络库.zip (95个子文件)
content
MyMuduo
include
Channel.hpp 3KB
NonCopyable.hpp 309B
TimeStamp.hpp 290B
Acceptor.hpp 844B
EventLoopThread.hpp 670B
Thread.hpp 764B
EpollPoller.hpp 693B
TcpServer.hpp 2KB
EventLoopThreadPool.hpp 1KB
Logger.hpp 3KB
InetAddress.hpp 538B
EventLoop.hpp 2KB
Poller.hpp 935B
TcpConnection.hpp 3KB
CurrentThread.hpp 301B
Socket.hpp 515B
Callbacks.hpp 564B
Buffer.hpp 3KB
CMakeLists.txt 331B
lib
autobuild.sh 535B
libmymuduo.so 2.31MB
.vscode
c_cpp_properties.json 484B
src
Thread.cpp 1KB
CMakeLists.txt 159B
InetAddress.cpp 712B
Buffer.cpp 1KB
EventLoop.cpp 4KB
CurrentThread.cpp 340B
Poller.cpp 285B
EventLoopThreadPool.cpp 2KB
Channel.cpp 2KB
Socket.cpp 2KB
TimeStamp.cpp 770B
TcpServer.cpp 4KB
EventLoopThread.cpp 1KB
EpollPoller.cpp 4KB
DefaultPoller.cpp 304B
Logger.cpp 776B
TcpConnection.cpp 7KB
Acceptor.cpp 2KB
build
CMakeFiles
Makefile2 4KB
feature_tests.c 688B
CMakeDirectoryInformation.cmake 628B
3.10.2
CompilerIdC
CMakeCCompilerId.c 18KB
a.out 8KB
CMakeDetermineCompilerABI_CXX.bin 8KB
CMakeCXXCompiler.cmake 5KB
CMakeSystem.cmake 398B
CMakeCCompiler.cmake 2KB
CMakeDetermineCompilerABI_C.bin 8KB
CompilerIdCXX
CMakeCXXCompilerId.cpp 17KB
a.out 8KB
cmake.check_cache 85B
feature_tests.cxx 10KB
feature_tests.bin 12KB
Makefile.cmake 7KB
progress.marks 3B
CMakeOutput.log 44KB
TargetDirectories.txt 295B
cmake_install.cmake 2KB
Makefile 4KB
src
CMakeFiles
mymuduo.dir
TcpConnection.cpp.o 850KB
TcpServer.cpp.o 1.11MB
CXX.includecache 6KB
link.txt 780B
EventLoopThreadPool.cpp.o 399KB
Poller.cpp.o 230KB
Logger.cpp.o 81KB
TimeStamp.cpp.o 83KB
DefaultPoller.cpp.o 42KB
EpollPoller.cpp.o 487KB
depend.internal 4KB
depend.make 8KB
Channel.cpp.o 230KB
InetAddress.cpp.o 82KB
flags.make 258B
Acceptor.cpp.o 278KB
CurrentThread.cpp.o 14KB
Thread.cpp.o 226KB
DependInfo.cmake 3KB
Socket.cpp.o 88KB
EventLoopThread.cpp.o 292KB
cmake_clean.cmake 978B
build.make 36KB
EventLoop.cpp.o 523KB
Buffer.cpp.o 154KB
progress.make 397B
CMakeDirectoryInformation.cmake 628B
progress.marks 3B
cmake_install.cmake 1KB
Makefile 19KB
CMakeCache.txt 12KB
example
testserver.cc 1KB
test 77KB
README.md 29KB
共 95 条
- 1
资源评论
生瓜蛋子
- 粉丝: 3873
- 资源: 6140
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功