设为首页 加入收藏

TOP

6.4.2 echo 服务的实现(1)
2013-10-07 16:02:52 来源: 作者: 【 】 浏览:56
Tags:6.4.2 echo 服务 实现

6.4.2 echo 服务的实现(1)

muduo 的使用非常简单,不需要从指定的类派生,也不用覆写虚函数,只需要注册几个回调函数去处理前面提到的三个半事件就行了。

下面以经典的echo 回显服务为例:

1. 定义EchoServer class,不需要派生自任何基类。

  1. examples/simple/echo/echo.h  
  2. 4 #include <muduo/net/TcpServer.h> 
  3. 5  
  4. 6 // RFC 862  
  5. 7 class EchoServer  
  6. 8 {  
  7. 9 public:  
  8. 10 EchoServer(muduo::net::EventLoop* loop,  
  9. 11 const muduo::net::InetAddress& listenAddr);  
  10. 12  
  11. 13 void start(); // calls server_.start();  
  12. 14  
  13. 15 private:  
  14. 16 void onConnection(const muduo::net::TcpConnectionPtr& conn);  
  15. 17  
  16. 18 void onMessage(const muduo::net::TcpConnectionPtr& conn,  
  17. 19 muduo::net::Buffer* buf,  
  18. 20 muduo::Timestamp time);  
  19. 21  
  20. 22 muduo::net::EventLoop* loop_;  
  21. 23 muduo::net::TcpServer server_;  
  22. 24 };  
  23. examples/simple/echo/echo.h 

在构造函数里注册回调函数。
  1. examples/simple/echo/echo.cc  
  2. 10 EchoServer::EchoServer(muduo::net::EventLoop* loop,  
  3. 11 const muduo::net::InetAddress& listenAddr)  
  4. 12 : loop_(loop),  
  5. 13 server_(loop, listenAddr, "EchoServer")  
  6. 14 {  
  7. 15 server_.setConnectionCallback(  
  8. 16 boost::bind(&EchoServer::onConnection, this, _1));  
  9. 17 server_.setMessageCallback(  
  10. 18 boost::bind(&EchoServer::onMessage, this, _1, _2, _3));  
  11. 19 }  
  12. examples/simple/echo/echo.cc 

2. 实现EchoServer::onConnection() 和EchoServer::onMessage()。
  1. examples/simple/echo/echo.cc  
  2. 26 void EchoServer::onConnection(const muduo::net::TcpConnectionPtr& conn)  
  3. 27 {  
  4. 28 LOG_INFO << "EchoServer - " << conn->peerAddress().toIpPort() << " -> "  
  5. 29 << conn->localAddress().toIpPort() << " is "  
  6. 30 << (conn->connected()   "UP" : "DOWN");  
  7. 31 }  
  8. 32  
  9. 33 void EchoServer::onMessage(const muduo::net::TcpConnectionPtr& conn,  
  10. 34 muduo::net::Buffer* buf,  
  11. 35 muduo::Timestamp time)  
  12. 36 {  
  13. 37 muduo::string msg(buf->retrieveAllAsString());  
  14. 38 LOG_INFO << conn->name() << " echo " << msg.size() << " bytes, "  
  15. 39 << "data received at " << time.toString();  
  16. 40 conn->send(msg);  
  17. 41 }  
  18. examples/simple/echo/echo.cc 

L37 和L40 是echo 服务的“业务逻辑”:把收到的数据原封不动地发回客户端。注意我们不用担心L40 的send(msg) 是否完整地发送了数据,因为muduo 网络库会帮我们管理发送缓冲区。

这两个函数体现了“基于事件编程(www.cppentry.com)”的典型做法,即程序主体是被动等待事件发生,事件发生之后网络库会调用(回调)事先注册的事件处理函数(event handler)。

在onConnection() 函数中, conn 参数是TcpConnection 对象的shared_ptr,TcpConnection::connected() 返回一个bool 值, 表明目前连接是建立还是断开,TcpConnection 的peerAddress() 和localAddress() 成员函数分别返回对方和本地的地址(以InetAddress 对象表示的IP 和port)。

在onMessage() 函数中,conn 参数是收到数据的那个TCP 连接;buf 是已经收到的数据,buf 的数据会累积,直到用户从中取走(retrieve)数据。注意buf是指针,表明用户代码可以修改(消费)buffer;time 是收到数据的确切时间,即epoll_wait(2) 返回的时间,注意这个时间通常比read(2) 发生的时间略早,可以用于正确测量程序的消息处理延迟。另外,Timestamp 对象采用pass-by-value,而不是pass-by-(const)reference,这是有意的,因为在x86-64 上可以直接通过寄存器传参。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇6.4.1 TCP 网络编程本质论 下一篇6.4.2 echo 服务的实现(2)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·MySQL 安装及连接-腾 (2025-12-25 06:20:28)
·MySQL的下载、安装、 (2025-12-25 06:20:26)
·MySQL 中文网:探索 (2025-12-25 06:20:23)
·Shell脚本:Linux Sh (2025-12-25 05:50:11)
·VMware虚拟机安装Lin (2025-12-25 05:50:08)