muduo库的简单使用

muduo是一个基于事件驱动的非阻塞网络库,采用C++和Boost库编写。

它的使用方法很简单,参考这篇文章:TCP网络编程本质论

里面有这么几句:

我认为,TCP 网络编程最本质的是处理三个半事件:

连接的建立,包括服务端接受 (accept) 新连接和客户端成功发起 (connect) 连接。
连接的断开,包括主动断开 (close 或 shutdown) 和被动断开 (read 返回 0)。
消息到达,文件描述符可读。这是最为重要的一个事件,对它的处理方式决定了网络编程的风格(阻塞还是非阻塞,如何处理分包,应用层的缓冲如何设计等等)。
消息发送完毕,这算半个。对于低流量的服务,可以不必关心这个事件;另外,这里“发送完毕”是指将数据写入操作系统的缓冲区,将由 TCP 协议栈负责数据的发送与重传,不代表对方已经收到数据。

所以,使用muduo库只需编写上面几处相关的逻辑即可。像套接字建立、epoll轮询这种例行公事的代码,我们不必再编写。

下面我们实现echo服务器,echo的核心逻辑只有一个,那就是将收到的信息回显给对方,所以这里我们只需关心消息到达这个事件即可。

代码如下:


#include <muduo/base/Logging.h>
#include <muduo/base/Timestamp.h>
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <muduo/net/TcpConnection.h> using namespace muduo;
using namespace muduo::net; void onConnection(const TcpConnectionPtr &conn)
{
LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> "
<< conn->localAddress().toIpPort() << " is "
<< (conn->connected() ? "UP" : "DOWN");
} void onMessage(const TcpConnectionPtr &conn,
Buffer *buf,
Timestamp time)
{
muduo::string msg(buf->retrieveAllAsString());
LOG_INFO << conn->name() << " echo " << msg.size() << " bytes, "
<< "data received at " << time.toString();
conn->send(msg);
} int main(int argc, const char *argv[])
{
EventLoop loop;
InetAddress addr("127.0.0.1", 8988);
TcpServer server(&loop, addr, "echo");
server.setConnectionCallback(&onConnection);
server.setMessageCallback(&onMessage);
server.start();
loop.loop();
return 0;
}

使用下列命令编译:

g++ -o echo echo.cc -lmuduo_net -lmuduo_base -lpthread

客户端采用netcat即可:

echo "hello" | nc localhost 8988

基于对象的使用方法

上面的使用方式是采用了全局函数,我们还可以将echo服务器封装成一个类:


#include <muduo/net/TcpServer.h>
#include <muduo/base/Logging.h>
#include <boost/bind.hpp>
#include <muduo/net/EventLoop.h> class EchoServer
{
public:
EchoServer(muduo::net::EventLoop* loop,
const muduo::net::InetAddress& listenAddr); void start(); // calls server_.start(); private:
void onConnection(const muduo::net::TcpConnectionPtr& conn); void onMessage(const muduo::net::TcpConnectionPtr& conn,
muduo::net::Buffer* buf,
muduo::Timestamp time); muduo::net::TcpServer server_;
}; EchoServer::EchoServer(muduo::net::EventLoop* loop,
const muduo::net::InetAddress& listenAddr)
: server_(loop, listenAddr, "EchoServer")
{
server_.setConnectionCallback(
boost::bind(&EchoServer::onConnection, this, _1));
server_.setMessageCallback(
boost::bind(&EchoServer::onMessage, this, _1, _2, _3));
} void EchoServer::start()
{
server_.start();
} void EchoServer::onConnection(const muduo::net::TcpConnectionPtr& conn)
{
LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> "
<< conn->localAddress().toIpPort() << " is "
<< (conn->connected() ? "UP" : "DOWN");
} void EchoServer::onMessage(const muduo::net::TcpConnectionPtr& conn,
muduo::net::Buffer* buf,
muduo::Timestamp time)
{
// 接收到所有的消息,然后回显
muduo::string msg(buf->retrieveAllAsString());
LOG_INFO << conn->name() << " echo " << msg.size() << " bytes, "
<< "data received at " << time.toString();
conn->send(msg);
} int main()
{
LOG_INFO << "pid = " << getpid();
muduo::net::EventLoop loop;
muduo::net::InetAddress listenAddr(2007);
EchoServer server(&loop, listenAddr);
server.start();
loop.loop();
}

后面陆续分析一些复杂的示例。

muduo库的简单使用-echo服务的编写的更多相关文章

  1. muduo库源码剖析(二) 服务端

    一. TcpServer类: 管理所有的TCP客户连接,TcpServer供用户直接使用,生命期由用户直接控制.用户只需设置好相应的回调函数(如消息处理messageCallback)然后TcpSer ...

  2. socket实现一个简单的echo服务

    服务端的实现: public class EchoServer{ //创建一个serverSocket private final ServerSocket serverSocket; //创建一个构 ...

  3. 构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介

    构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介 熟悉将用于 Apache Tuscany SCA for C++ 的 API.您将通过本文了解该 API 的主要组 ...

  4. 简单ESB的服务架构

    简单ESB的服务架构 这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1. ...

  5. 新项目架构从零开始(三)------基于简单ESB的服务架构

    这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1.Common 在Com ...

  6. 简单 TCP/IP 服务功能

    本主题使用每台 Windows 计算机上提供的 Echo 和 Quote of the Day 服务.在所有 Windows 版本中都提供了简单 TCP/IP 服务功能.该功能会提供了以下服务:Cha ...

  7. muduo库整体架构简析

    muduo是一个高质量的Reactor网络库,采用one loop per thread + thread loop架构实现,代码简洁,逻辑清晰,是学习网络编程的很好的典范. muduo的代码分为两部 ...

  8. gRPC初探——概念介绍以及如何构建一个简单的gRPC服务

    目录 引言 1. gRPC简介 2. 使用Protocol Buffers进行服务定义 2.1 定义消息 2.2 定义服务接口 3.构建简单的gRPC服务 3.1 编写proto文件,定义消息和接口 ...

  9. Python网络编程--Echo服务

    Python网络编程--Echo服务 学习网络编程必须要练习的三个小项目就是Echo服务,Chat服务和Proxy服务.在接下来的几篇文章会详细介绍. 今天就来介绍Echo服务,Echo服务是最基本的 ...

随机推荐

  1. 1.Java内存区域

    Java虚拟机在执行java程序的过程中会把他管理的内存划分为若干个不同的数据区域各自用途.创建以及销毁时间各不相同.有的随着虚拟机进行的启动而存在,有的区域依赖于线程的启动和结束而建立以及销毁.如图 ...

  2. poj 3264 Balanced Lineup (RMQ)

    /******************************************************* 题目: Balanced Lineup(poj 3264) 链接: http://po ...

  3. zendstudio 声明变量类型,让变量自动方法提示

    zendstudio 行内注释, 显式声明变量类型,让变量自动方法提示 $out = []; /* @var $row \xxyy\SizeEntity */ foreach ($rows[ 'lis ...

  4. android里R.layout.的问题

    今天,在Exlipse里的一个项目在.java文件里写  setContentView(R.layout.activity_problem);时,显示错误,以为是R.java文件里没有对应的activ ...

  5. Odoo下拉动作列表

  6. zz---Tomcat服务器下部署项目几种方式

    http://blog.sina.com.cn/s/blog_550281c60101hvrs.html 一.静态部署1.直接将web项目文件件拷贝到webapps 目录中     Tomcat的We ...

  7. JQuery教程

    1.是javaScript库(js文件) 2.使用:script标签 3.语法:$开头 $().action() 列如:$('div').css("color",'red'); 4 ...

  8. html5新特性之音频、视频

    1.视频 标签video video标签的属性 属性 描述 autoplay 视频就绪后自动播放 preload 视频在页面加载时加载 loop 视频播放完成后循环播放 controls 显示控件 s ...

  9. python基础整理笔记(三)

    一. python的几种入参形式:1.普通参数: 普通参数就是最一般的参数传递形式.函数定义处会定义需要的形参,然后函数调用处,需要与形参一一对应地传入实参. 示例: def f(a, b): pri ...

  10. c# 后台调前台的js

    ScriptManager.RegisterStartupScript(this.Page, typeof(Page), "", "<script type=\&q ...