# 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
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
适合学习/练手、毕业设计、课程设计、期末/期中/大作业、工程实训、相关项目/竞赛学习等。 项目具有较高的学习借鉴价值,也可直接拿来修改复现。可以在这些基础上学习借鉴进行修改和扩展,实现其它功能。 可放心下载学习借鉴,你会有所收获。 —— 博主领域:嵌入式领域&人工智能&软件开发。 对于学习和实践,选择合适的项目和资源确实是一种有效的方式。 在进行毕业设计、课程设计或大作业时,选择具备学习借鉴价值的项目可以帮助你理解和应用所学知识,同时也可以通过修改和扩展来实现其他功能。 通过参与实际项目,你可以应用所学的理论知识,深入了解软件开发或其他领域的实践流程和技术要求。 # 注意 1. 本资源仅用于开源学习和技术交流。不可商用等,一切后果由使用者承担。 2. 部分字体以及插图等来自网络,若是侵权请联系删除。
资源推荐
资源详情
资源评论
收起资源包目录
基于C++11的muduo网络库.zip (95个子文件)
c_code1
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
资源评论
阿齐Archie
- 粉丝: 1w+
- 资源: 2301
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功