muduo库的简单使用-echo服务的编写
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服务的编写的更多相关文章
- muduo库源码剖析(二) 服务端
		一. TcpServer类: 管理所有的TCP客户连接,TcpServer供用户直接使用,生命期由用户直接控制.用户只需设置好相应的回调函数(如消息处理messageCallback)然后TcpSer ... 
- socket实现一个简单的echo服务
		服务端的实现: public class EchoServer{ //创建一个serverSocket private final ServerSocket serverSocket; //创建一个构 ... 
- 构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介
		构建简单的 C++ 服务组件,第 1 部分: 服务组件体系结构 C++ API 简介 熟悉将用于 Apache Tuscany SCA for C++ 的 API.您将通过本文了解该 API 的主要组 ... 
- 简单ESB的服务架构
		简单ESB的服务架构 这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1. ... 
- 新项目架构从零开始(三)------基于简单ESB的服务架构
		这几个月一直在修改架构,所以迟迟没有更新博客. 新的架构是一个基于简单esb的服务架构,主要构成是esb服务注册,wcf服务,MVC项目构成. 首先,我门来看一看解决方案, 1.Common 在Com ... 
- 简单 TCP/IP 服务功能
		本主题使用每台 Windows 计算机上提供的 Echo 和 Quote of the Day 服务.在所有 Windows 版本中都提供了简单 TCP/IP 服务功能.该功能会提供了以下服务:Cha ... 
- muduo库整体架构简析
		muduo是一个高质量的Reactor网络库,采用one loop per thread + thread loop架构实现,代码简洁,逻辑清晰,是学习网络编程的很好的典范. muduo的代码分为两部 ... 
- gRPC初探——概念介绍以及如何构建一个简单的gRPC服务
		目录 引言 1. gRPC简介 2. 使用Protocol Buffers进行服务定义 2.1 定义消息 2.2 定义服务接口 3.构建简单的gRPC服务 3.1 编写proto文件,定义消息和接口 ... 
- Python网络编程--Echo服务
		Python网络编程--Echo服务 学习网络编程必须要练习的三个小项目就是Echo服务,Chat服务和Proxy服务.在接下来的几篇文章会详细介绍. 今天就来介绍Echo服务,Echo服务是最基本的 ... 
随机推荐
- SDK,monkey 浅谈
			最近在工作之余碰到一些手机测试的新手,现在测试手机的基本都是android的系统. 然后在遇到压力测试的时候就开始遇到问题了. 压力测试用什么工具?怎么使用?工具怎么来? 今天遇到两个人都问我SDK是 ... 
- margin设置为百分比的含义
			<!DOCTYPE html> <html> <head> <title>magin为百分比</title> </head> & ... 
- HDU 2689Sort it 树状数组 逆序对
			Sort it Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ... 
- 深入浅出Symfony2 - 如何提高网站响应速度 [转]
			简介 Symfony2是一个基于PHP语言的Web开发框架,有着开发速度快.性能高等特点.但Symfony2的学习曲线也比较陡峭,没有经验的初学者往往需要一些练习才能掌握其特性.相对其他框架,Symf ... 
- C# 常见面试题1
			1.WinForm遍历控件 foreach (System.Windows.Forms.Control control in this.Controls) { if (control is Syste ... 
- nodejs+express使用html和jade
			nodejs+express经常会看到使用jade视图引擎,但是有些人想要访问普通的html页面,这也是可以的: var express = require('express'); var port ... 
- 数论 : 模运算法则(poj 1152)
			题目:An Easy Problem! 题意:求给出数的最小进制. 思路:暴力WA: discuss中的idea: 给出数ABCD,若存在n 满足 (A* n^3 +B*n^2+C*n^1+D*n^0 ... 
- 斯坦福第十三课:聚类(Clustering)
			13.1 无监督学习:简介 13.2 K-均值算法 13.3 优化目标 13.4 随机初始化 13.5 选择聚类数 13.1 无监督学习:简介 在这个视频中,我将开始介绍聚类算法.这将是一个 ... 
- 7.1	 Java中的堆和栈
			栈与堆都是Java用来在Ram中存放数据的地方.Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new.newarray.ane ... 
- MacOS 10.8更新SVN到1.8.4的问题和解决方法
			因为要导入以前的项目,但以前项目里内含有的svn信息,所以xcode默认安装的svn1.6是无法删除svn信息,据说需要svn1.7才能清除掉svn信息.所以必须要升级svn的版本. 我在网上找了各种 ... 
