logo资料库

Muduo_网络库使用手册.pdf

第1页 / 共140页
第2页 / 共140页
第3页 / 共140页
第4页 / 共140页
第5页 / 共140页
第6页 / 共140页
第7页 / 共140页
第8页 / 共140页
资料共140页,剩余部分请下载后查看
1 Muduo 网络库简介
1.1 由来
1.2 安装
1.2.1 在自己的程序中使用 muduo
1.3 目录结构
1.3.1 代码结构
1.3.2 例子
1.3.3 线程模型
1.4 使用教程
1.4.1 TCP 非阻塞网络编程本质论
1.4.2 Echo服务的实现
1.4.3 七步实现Finger服务
1.5 性能评测
1.5.1 muduo 与 boost asio、libevent2 吞吐量对比
1.5.2 击鼓传花:对比 muduo 与 libevent2 的事件处理效率
1.5.3 muduo 与 nginx 吞吐量对比
1.5.4 muduo 与 ZeroMQ 的延迟对比
1.6 详解Muduo多线程模型
1.6.1 数独求解服务器
1.6.2 常见的并发网络服务程序设计方案
1.6.3 结语
2 Muduo 编程示例
2.1 五个简单 TCP 协议
2.1.1 discard
2.1.2 daytime
2.1.3 time
2.1.4 echo
2.1.5 chargen
2.1.6 五合一
2.2 文件传输
2.2.1 为什么 TcpConnection::shutdown() 没有直接关闭 TCP 连接?
2.3 Boost.Asio 的聊天服务器
2.3.1 TCP 分包
2.3.2 聊天服务
2.3.3 消息格式
2.3.4 编解码器 LengthHeaderCodec
2.3.5 服务端的实现
2.3.6 客户端的实现
2.4 Buffer 类的设计与使用
2.4.1 Muduo 的 IO 模型
2.4.2 为什么 non-blocking 网络编程中应用层 buffer 是必须的?
2.4.3 Buffer 的要求
2.4.4 Muduo Buffer 的数据结构
2.4.5 Muduo Buffer 的操作
2.4.6 其他设计方案
2.4.7 性能是不是问题?看跟谁比
2.5 一种自动反射消息类型的 Google Protobuf 网络传输方案
2.5.1 网络编程中使用 protobuf 的两个问题
2.5.2 山寨做法
2.5.3 根据 type name 反射自动创建 Message 对象
2.5.4 Protobuf 传输格式
2.6 在 muduo 中实现 Protobuf 编解码器与消息分发器
2.6.1 什么是编解码器 codec?
2.6.2 实现 ProtobufCodec
2.6.3 消息分发器 dispatcher 有什么用?
2.6.4 ProtobufCodec 与 ProtobufDispatcher 的综合运用
2.6.5 ProtobufDispatcher 的两种实现
2.6.6 ProtobufCodec 和 ProtobufDispatcher 有何意义?
2.7 限制服务器的最大并发连接数
2.7.1 为什么要限制并发连接数?
2.7.2 Muduo 中限制并发连接数
2.8 定时器
2.8.1 程序中的时间
2.8.2 Linux 时间函数
2.8.3 Muduo 的定时器接口
2.8.4 Boost.Asio Timer 示例
2.8.5 Java Netty 示例
2.9 测量两台机器的网络延迟
2.10 用 Timing wheel 踢掉空闲连接
2.10.1 Timing wheel 原理
2.10.2 代码实现与改进
2.11 简单的消息广播服务
2.11.1 多现程的高效广播
2.12 “串并转换”连接服务器及其自动化测试
2.12.1 自动化测试
2.13 socks4a 代理服务器
2.13.1 TCP 中继器
2.13.2 Socks4a 代理服务器
2.13.3 n:1 与 1:n 连接转发
2.14 短址服务
2.15 与其他库集成
2.15.1 UDNS
2.15.2 c-ares DNS
2.15.3 curl
2.15.4 更多
Muduo 网络库使用手册 by 陈硕 1 Muduo 网络库使用手册 陈硕 (giantchen@gmail.com) 最后更新 2012-6-26 版权声明 本作品采用“Creative Commons 署名 -非商业性使用 -禁止演绎 3.0 Unported 许可 协议 (cc by-nc-nd)”进行许可。http://creativecommons.org/licenses/by-nc-nd/3.0/ 内容一览 1 Muduo 网络库简介 1.1 由来 . . 1.2 安装 . . . . . . . . 1.3 目录结构 . . 1.4 使用教程 . . 1.5 性能评测 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6 详解 Muduo 多线程模型 . 2 Muduo 编程示例 2.1 五个简单 TCP 协议 . . 2.2 文件传输 . . . . . . . . . . . . 2.3 Boost.Asio 的聊天服务器 . 2.4 Buffer 类的设计与使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 一种自动反射消息类型的 Google Protobuf 网络传输方案 . . 2.6 在 muduo 中实现 Protobuf 编解码器与消息分发器 . 2.7 限制服务器的最大并发连接数 . . 2.8 定时器 . . . . . . . . . . . 2.9 测量两台机器的网络延迟 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 6 . . . . 13 . 22 . . . . . . . 35 49 . . . 50 . 57 . . . . . . . . . 66 76 91 . 100 . 108 . 112 . . 119 www.chenshuo.com
Muduo 网络库简介 by 陈硕 2 2.10 用 Timing wheel 踢掉空闲连接 . 2.11 简单的消息广播服务 . . . . . . . . . . . . . . . . . . . . 2.12 “串并转换”连接服务器及其自动化测试 . 2.13 socks4a 代理服务器 . . 2.14 短址服务 . . . . 2.15 与其他库集成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 . 128 . 131 . 136 . 139 . 140 www.chenshuo.com
1 Muduo 网络库简介 1.1 由来 2010 年 3 月我写了一篇《学之者生,用之者死——ACE 历史与简评》1 ,其中提 到“我心目中理想的网络库”的样子: • 线程安全,原生支持多核多线程 • 不考虑可移植性,不跨平台,只支持 Linux,不支持 Windows。 • 主要支持 x86-64,兼顾 IA32。(实际上 muduo 也可以运行在 ARM 上。) • 不支持 UDP,只支持 TCP。 • 不支持 IPv6,只支持 IPv4。 • 不考虑广域网应用,只考虑局域网。(实际上 muduo 也可以用在广域网上。) • 不考虑公网,只考虑内网。不为安全性做特别的增强。 • 只支持一种使用模式:non-blocking IO + one event loop per thread,不支持阻 塞 IO。 • API 简单易用,只暴露具体类和标准库里的类。API 不使用 non-trivial tem- plates,也不使用虚函数。 • 只满足常用需求的 90%,不面面俱到,必要的时候以 app 来适应 lib。 • 只做 library,不做成 framework。 • 争取全部代码在 5000 行以内(不含测试)。(目前 muduo 网络部分的核心代码 约 4400 行。) • 在不增加复杂度的前提下可以支持 FreeBSD/Darwin,方便将来用 Mac 作为 开发用机,但不为它做性能优化。也就是说 IO multiplexing 使用 poll(2) 和 epoll(4)。 1http://blog.csdn.net/Solstice/archive/2010/03/10/5364096.aspx 3
Muduo 网络库简介 by 陈硕 4 • 以上条件都满足时,可以考虑搭配 Google Protocol Buffers RPC 在想清楚这些目标之后,我开始第三次尝试编写自己的 C++ 网络库。与前两次 不同,这次我一开始就想好了库的名字,叫 muduo (木铎),并在 Google code 上 创建了项目:http://code.google.com/p/muduo/。Muduo 以 git 为版本管理工具, 托管于 https://github.com/chenshuo/muduo。muduo 的主体内容在 2010 年 5 月 底已经基本完成,8 月底发布 0.1.0 版,现在(2012 年 6 月)的最新版本是 0.7.0。 1.2 安装 源文件 tar 包的下载地址:http://code.google.com/p/muduo/downloads/list, 此处以 muduo-0.7.0-beta.tar.gz 为例。 Muduo 使用了 Linux 较新的系统调用 2,要求 Linux 的内核版本大于 2.6.28。 我自己用 Debian 6.0 Squeeze / Ubuntu 10.04 LTS 作为主要开发环境(内核版本 2.6.32),以 g++ 4.4 为主要编译器版本,在 32 位和 64 位 x86 系统都编译测试通过。 Muduo 在 Fedora 13 和 CentOS 6 上也能正常编译运行,还有热心网友为 Arch Linux 编写了 AUR 文件 3。 如果要在较旧的 Linux 2.6 内核 4 上使用 muduo,可以参考 backport.diff 来修 改代码。不过这些系统上没有充分测试,仅仅是编译和冒烟测试通过。另外 muduo 也可以运行在嵌入式系统中,我在 Samsung S3C2440 开发板(ARM9)上成功运行 了 muduo 的多个示例。当时 Linux 内核版本为 2.6.32,代码需略作改动,请参考 armlinux.diff。 Muduo 采用 CMake 5 为 build system,安装方法: $ sudo apt-get install cmake Muduo 依赖 Boost 6,很容易安装: $ sudo apt-get install libboost1.40-dev 或 $ sudo apt-get install libboost1.42-dev 2主要是 timerfd 和 eventfd。 3http://aur.archlinux.org/packages.php?ID=49251 4例如 Debian 5.0 Lenny、Ubuntu 8.04、CentOS 5 等等发行版。 5最好不低于 2.8 版,CentOS 6 自带的 2.6 版也能用,但是无法自动识别 Protobuf 库。 6核心库只依赖 TR1,示例代码用到了其他 boost 库 www.chenshuo.com
Muduo 网络库简介 by 陈硕 5 muduo 有三个非必须的依赖库:curl、c-ares DNS、Google Protobuf,如果安装了 这三个库,cmake 会自动多编译一些示例。 $ sudo apt-get install libcurl4-openssl-dev libc-ares-dev $ sudo apt-get install protobuf-compiler libprotobuf-dev 编译方法很简单: $ tar zxf muduo-0.7.0-beta.tar.gz $ cd muduo/ $ ./build.sh -j2 编译 muduo 库和它自带的例子,生成的可执行文件和静态库文件 分别位于 ../build/debug/{bin,lib} $ ./build.sh install 以上命令将 muduo 头文件和库文件安装到 ../build/debug-install/{include,lib} 如果要编译 release 版(以 -O2 优化),可执行 $ BUILD_TYPE=release ./build.sh -j2 编译 muduo 库和它自带的例子,生成的可执行文件和静态库文件 分别位于 ../build/release/{bin,lib} $ BUILD_TYPE=release ./build.sh install 以上命令将 muduo 头文件和库文件安装到 ../build/release-install/{include,lib} 在 muduo 1.0 正式发布之后,BUILD_TYPE 的默认值会改成 release。 编译完成之后请试运行其中的例子。比如 bin/inspector_test ,然后通过浏览器 访问 http://10.0.0.10:12345/ 或 http://10.0.0.10:12345/proc/status,其中 10.0.0.10 替换为你的 Linux box 的 IP。 1.2.1 在自己的程序中使用 muduo Muduo 是静态链接 7 的 C++ 程序库,使用 muduo 库的时候,只需要设置好头文 件路径(例如../build/debug-install/include)和库文件路径(例如../build/debug- install/lib)并链接相应的静态库文件(-lmuduo_net -lmuduo_base)即可。下面这 个示范项目展示了如何使用 CMake 和普通 make 编译基于 muduo 的程序 https://github.com/chenshuo/muduo-tutorial。 7原因是在分布式系统中正确安全地发布动态库的成本很高,见第 ?? 章。 www.chenshuo.com
Muduo 网络库简介 by 陈硕 1.3 目录结构 Muduo 的目录结构如下。 6 muduo |-- build.sh |-- ChangeLog |-- CMakeLists.txt |-- License |-- README |-- muduo | | | | | | |-- examples \-- TODO |-- base \-- net muduo 库的主体 与网络无关的基础代码,位于 ::muduo namespace,包括线程库 网络库,位于 ::muduo::net namespace poll(2) 和 epoll(4) 两种 IO multiplexing 后端 一个简单的可嵌入的 web 服务器 基于以上 web 服务器的“窥探器”,用于报告进程的状态 |-- poller |-- http |-- inspect \-- protorpc 简单实现 Google Protobuf RPC,不推荐使用 丰富的示例 Muduo 的 源 代 码 文 件 名 与 class 名 相 同,例 如 ThreadPool class 的 定 义 是 muduo/base/ThreadPool.h,其实现位于 muduo/base/ThreadPool.cc。 基础库 muduo/base 目录是一些基础库,都是用户可见的类,内容包括 muduo \-- base |-- AsyncLogging.{h,cc} |-- Atomic.h |-- BlockingQueue.h |-- BoundedBlockingQueue.h |-- Condition.h |-- copyable.h |-- CountDownLatch.{h,cc} |-- Date.{h,cc} |-- Exception.{h,cc} |-- Logging.{h,cc} |-- Mutex.h |-- ProcessInfo.{h,cc} |-- Singleton.h |-- StringPiece.h |-- tests |-- Thread.{h,cc} |-- ThreadLocal.h |-- ThreadLocalSingleton.h |-- ThreadPool.{h,cc} 异步日志 backend 原子操作与原子整数 无界阻塞队列(消费者生产者队列) 有界阻塞队列 条件变量,与 Mutex 一同使用 一个空基类,用于标识 (tag) 值类型 “倒计时门闩”同步 Julian 日期库(即公历) 带 stack trace 的异常基类 简单的日志,可搭配 AsyncLogging 使用 互斥器 进程信息 线程安全的 singleton 从 Google 开源代码借用的字符串参数传递类型 测试代码 线程对象 线程局部数据 每个线程一个 singleton 简单的固定大小线程池 www.chenshuo.com
Muduo 网络库简介 by 陈硕 7 |-- Timestamp.{h,cc} |-- TimeZone.{h,cc} \-- Types.h UTC 时间戳 时区与夏令时 基本类型的声明,包括 muduo::string 网络核心库 Muduo 是基于 Reactor 模式的网络库,其核心是个事件循环 EventLoop,用于 响应计时器和 IO 事件。Muduo 采用基于对象(object based)而非面向对象(object oriented)的设计风格,其事件回调接口多以 boost::function + boost::bind 表达,用 户在使用 muduo 的时候不需要继承其中的 class。 网络库核心位于 muduo/net 和 muduo/net/poller,一共不到 4300 行代码,以 下灰底表示用户不可见的内部类。 muduo \-- net |-- Acceptor.{h,cc} |-- Buffer.{h,cc} |-- Callbacks.h |-- Channel.{h,cc} |-- CMakeLists.txt |-- Connector.{h,cc} |-- Endian.h |-- EventLoop.{h,cc} |-- EventLoopThread.{h,cc} |-- EventLoopThreadPool.{h,cc} |-- InetAddress.{h,cc} |-- Poller.{h,cc} |-- poller | | | |-- Socket.{h,cc} |-- SocketsOps.{h,cc} |-- TcpClient.{h,cc} |-- TcpConnection.{h,cc} |-- TcpServer.{h,cc} |-- tests |-- Timer.{h,cc} |-- TimerId.h \-- TimerQueue.{h,cc} |-- DefaultPoller.cc |-- EPollPoller.{h,cc} \-- PollPoller.{h,cc} 网络附属库 接受器,用于服务端接受连接 缓冲区,非阻塞 IO 必备 用于每个 Socket 连接的事件分发 连接器,用于客户端发起连接 网络字节序与本机字节序的转换 事件分发器 新建一个专门用于 EventLoop 的线程 Muduo 默认多线程 IO 模型 IP 地址的简单封装, IO multiplexing 的基类接口 IO multiplexing 的实现 根据环境变量 MUDUO_USE_POLL 选择后端 基于 epoll(4) 的 IO multiplexing 后端 基于 poll(2) 的 IO multiplexing 后端 封装 Sockets 描述符,负责关闭连接 封装底层的 Sockets API TCP 客户端 muduo 里最大的一个类,有 300 多行 TCP 服务端 简单测试 以下几个文件与定时器回调相关 网络库有一些附属模块,它们不是核心内容,在使用的时候需要链接相应的 库,例如 -lmuduo_http, -lmuduo_inspect 等等。HttpServer 和 Inspector 暴露出一 个 http 界面,用于监控进程的状态,类似于 Java JMX。见第 ?? 节。 www.chenshuo.com
Muduo 网络库简介 by 陈硕 8 附属模块位于 muduo/net/{http,inspect,protorpc} 等处。 muduo \-- net |-- CMakeLists.txt |-- HttpContext.h |-- HttpRequest.h |-- HttpResponse.{h,cc} |-- HttpServer.{h,cc} \-- tests/HttpServer_test.cc 示范如何在程序中嵌入 http 服务器 |-- http 不打算做成通用的 http 服务器,这只是简陋而不完整 http 协议实现 | | | | | | |-- inspect | | | | \-- protorpc |-- CMakeLists.txt |-- Inspector.{h,cc} |-- ProcessInspector.{h,cc} \-- tests/Inspector_test.cc 示范暴露程序状态,包括内存使用和文件描述符 基于 http 协议的窥探器,用于报告进程的状态 简单实现 Google Protobuf RPC |-- CMakeLists.txt |-- google-inl.h |-- RpcChannel.{h,cc} |-- RpcCodec.{h,cc} |-- rpc.proto \-- RpcServer.{h,cc} 1.3.1 代码结构 Muduo 的头文件明确分为客户可见和客户不可见两类。以下是安装之后暴露 的头文件和库文件。对于使用 muduo 库而言,只需要掌握 5 个关键类:Buffer、 EventLoop、TcpConnection、TcpClient、TcpServer。 头文件 基础库,同前,略 网络核心库 \-- muduo |-- base \-- net |-- include | | | | | | | | | | | | | | | | | | |-- Buffer.h |-- Callbacks.h |-- Endian.h |-- EventLoop.h |-- EventLoopThread.h |-- InetAddress.h |-- TcpClient.h |-- TcpConnection.h |-- TcpServer.h |-- TimerId.h |-- http | | | |-- HttpRequest.h |-- HttpResponse.h \-- HttpServer.h 以下为网络附属库的头文件 www.chenshuo.com
分享到:
收藏