muduo的使用教程2019-11-02

muduo只支持Linux2.6.x下的并发非阻塞TCP网络编程,它的核心是每个IO线程一个事件循环,把IO事件分发到回调函数上。

muduo把以前调用recv(2)来接收数据,调用accept(2)来接收新连接,调用send(2)发送数据转换为注册一个收数据的回调,网络库收到数据就回调我,直接把数据提供给我;注册一个接收连接的回调,网络库接收新的连接会回调我,直接把新的连接对象传给我;需要发送数据的时候,只管往连接中写,网络库会负责无阻塞的发送。

TCP网络编程本质是处理三个半事件:

1、建立连接。

2、断开连接。

3、消息到达,文件描述符可读。

3.5、消息发送完毕。

//echo服务实现

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(

      std::bind(&EchoServer::onConnection, this, _1));

  server_.setMessageCallback(

      std::bind(&EchoServer::onMessage, this, _1, _2, _3));

}


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);

}


finger服务实现

1、拒绝连接。什么都不做,程序空等。

#include "muduo/net/EventLoop.h"

using namespace muduo;

using namespace muduo::net;

int main()

{

  EventLoop loop;

  loop.loop();

}


2、接受新连接。在1079端口侦听新连接,接受连接之后什么都不做,程序空等,muduo会自动丢弃收到的数据。

#include "muduo/net/EventLoop.h"

#include "muduo/net/TcpServer.h"

using namespace muduo;

using namespace muduo::net;

int main()

{

  EventLoop loop;

  TcpServer server(&loop, InetAddress(1079), "Finger");

  server.start();

  loop.loop();

}

3、主动断开连接,接受新连接之后主动断开。

include "muduo/net/EventLoop.h"

#include "muduo/net/TcpServer.h"

using namespace muduo;

using namespace muduo::net;

void onConnection(const TcpConnectionPtr& conn)

{

  if (conn->connected())

  {

    conn->shutdown();

  }

}

int main()

{

  EventLoop loop;

  TcpServer server(&loop, InetAddress(1079), "Finger");

  server.setConnectionCallback(onConnection);

  server.start();

  loop.loop();

}

4、读取用户名,然后断开连接。

#include "muduo/net/EventLoop.h"

#include "muduo/net/TcpServer.h"

using namespace muduo;

using namespace muduo::net;

void onMessage(const TcpConnectionPtr& conn,

               Buffer* buf,

               Timestamp receiveTime)

{

  if (buf->findCRLF())

  {

    conn->shutdown();

  }

}

int main()

{

  EventLoop loop;

  TcpServer server(&loop, InetAddress(1079), "Finger");

  server.setMessageCallback(onMessage);

  server.start();

  loop.loop();

}

5、读取用户名,输出错误信息,然后断开连接。

#include "muduo/net/EventLoop.h"

#include "muduo/net/TcpServer.h"

using namespace muduo;

using namespace muduo::net;

void onMessage(const TcpConnectionPtr& conn,

               Buffer* buf,

               Timestamp receiveTime)

{

  if (buf->findCRLF())

  {

    conn->send("No such user\r\n");

    conn->shutdown();

  }

}

int main()

{

  EventLoop loop;

  TcpServer server(&loop, InetAddress(1079), "Finger");

  server.setMessageCallback(onMessage);

  server.start();

  loop.loop();

}

6、从空的UserMap里查找用户。

#include "muduo/net/EventLoop.h"

#include "muduo/net/TcpServer.h"

#include <map>

using namespace muduo;

using namespace muduo::net;

typedef std::map<string, string> UserMap;

UserMap users;

string getUser(const string& user)

{

  string result = "No such user";

  UserMap::iterator it = users.find(user);

  if (it != users.end())

  {

    result = it->second;

  }

  return result;

}

void onMessage(const TcpConnectionPtr& conn,

               Buffer* buf,

               Timestamp receiveTime)

{

  const char* crlf = buf->findCRLF();

  if (crlf)

  {

    string user(buf->peek(), crlf);

    conn->send(getUser(user) + "\r\n");

    buf->retrieveUntil(crlf + 2);

    conn->shutdown();

  }

}

int main()

{

  EventLoop loop;

  TcpServer server(&loop, InetAddress(1079), "Finger");

  server.setMessageCallback(onMessage);

  server.start();

  loop.loop();

}

7、在UserMap里添加一个用户。

#include "muduo/net/EventLoop.h"

#include "muduo/net/TcpServer.h"

#include <map>

using namespace muduo;

using namespace muduo::net;

typedef std::map<string, string> UserMap;

UserMap users;

string getUser(const string& user)

{

  string result = "No such user";

  UserMap::iterator it = users.find(user);

  if (it != users.end())

  {

    result = it->second;

  }

  return result;

}

void onMessage(const TcpConnectionPtr& conn,

               Buffer* buf,

               Timestamp receiveTime)

{

  const char* crlf = buf->findCRLF();

  if (crlf)

  {

    string user(buf->peek(), crlf);

    conn->send(getUser(user) + "\r\n");

    buf->retrieveUntil(crlf + 2);

    conn->shutdown();

  }

}

int main()

{

  users["schen"] = "Happy and well";

  EventLoop loop;

  TcpServer server(&loop, InetAddress(1079), "Finger");

  server.setMessageCallback(onMessage);

  server.start();

  loop.loop();

}

TCP长连接性能不错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值