当前位置:编程学习 > C/C++ >>

Muduo网络编程示例之一:五个简单 TCP 协议

discard
Discard 恐怕算是最简单的长连接 TCP 应用层协议,它只需要关注“三个半事件”中的“消息/数据到达”事件,事件处理函数如下:

   1: void DiscardServer::onMessage(const muduo::net::TcpConnectionPtr& conn,  

 2:                  muduo::net::Buffer* buf,  

 3:                  muduo::Timestamp time)  

4: {  

5:   string msg(buf->retrieveAsString());  // 取回读到的全部数据

   6:   LOG_INFO << conn->name() << " discards " << msg.size() << " bytes at " << time.toString();  

 7: }剩下的都是例行公事的代码:定义一个 DiscardServer class,以 TcpServer 为成员。   1: #ifndef MUDUO_EXAMPLES_SIMPLE_DISCARD_DISCARD_H   2: #define MUDUO_EXAMPLES_SIMPLE_DISCARD_DISCARD_H   3:     4: #include    5:     6: // RFC 863   7: class DiscardServer  

8: {  

9:  public: 

10:   DiscardServer(muduo::net::EventLoop* loop,

  11:                 const muduo::net::InetAddress& listenAddr); 

12:  

  13:   void start(); 

14:   

 15:  private: 

 16:   void onConnection(const muduo::net::TcpConnectionPtr& conn); 

 17:   

 18:   void onMessage(const muduo::net::TcpConnectionPtr& conn, 

19:                  muduo::net::Buffer* buf,

  20:                  muduo::Timestamp time); 

 21:   

22:   muduo::net::EventLoop* loop_; 

 23:   muduo::net::TcpServer server_; 

24: }; 

25:   

26: #endif  // MUDUO_EXAMPLES_SIMPLE_DISCARD_DISCARD_H注册回调函数  

 1: DiscardServer::DiscardServer(muduo::net::EventLoop* loop,  

2:                              const muduo::net::InetAddress& listenAddr)

3:   : loop_(loop),  

4:     server_(loop, listenAddr, "DiscardServer")  

 5: {  

6:   server_.setConnectionCallback(  

7:       boost::bind(&DiscardServer::onConnection, this, _1));  

 8:   server_.setMessageCallback(  

9:       boost::bind(&DiscardServer::onMessage, this, _1, _2, _3)); 

10: } 

11:   

12: void DiscardServer::start() 

13: { 

14:   server_.start(); 

 15: }

处理连接与数据事件  

 1: void DiscardServer::onConnection(const muduo::net::TcpConnectionPtr& conn)  

2: {  

3:   LOG_INFO << "DiscardServer - " << conn->peerAddress().toHostPort() << " -> "  

4:     << conn->localAddress().toHostPort() << " is "  

5:     << (conn->connected() ? "UP" : "DOWN");  

 6: }  

7:    

 8: void DiscardServer::onMessage(const muduo::net::TcpConnectionPtr& conn,  

9:                  muduo::net::Buffer* buf, 

 10:                  muduo::Timestamp time) 

11: { 

12:   string msg(buf->retrieveAsString()); 

13:   LOG_INFO << conn->name() << " discards " << msg.size() << " bytes at " << time.toString(); 

14: }

在 main() 里用 EventLoop 让整个程序转起来  

1: #include "discard.h"  

2:    

3: #include   

 4: #include   

5:    

 6: using namespace muduo;  

7: using namespace muduo::net; 

 8:    

9: int main() 

10: { 

11:   LOG_INFO << "pid = " << getpid(); 

12:   EventLoop loop; 

13:   InetAddress listenAddr(2009); 

14:   DiscardServer server(&loop, listenAddr); 

15:   server.start(); 

 16:   loop.loop(); 

17: }daytime
Daytime 是短连接协议,在发送完当前时间后,由服务端主动断开连接。它只需要关注“三个半事件”中的“连接已建立”事件,事件处理函数如下:

   1: void DaytimeServer::onConnection(const muduo::net::TcpConnectionPtr& conn)  

 2: {  

 3:   LOG_INFO << "DaytimeServer - " << conn->peerAddress().toHostPort() << " -> "  

4:     << conn->localAddress().toHostPort() << " is "  

 5:     << (conn->connected() ? "UP" : "DOWN");  

6:   if (conn->connected())   7:   {   8:     conn->send(Timestamp::now().toFormattedString() + " "); // 发送时间字符串   9:     conn->shutdown(); // 主动断开连接  10:   }  11: }剩下的都是例行公事的代码,为节省篇幅,此处从略,请阅读 muduo/examples/易做图/daytime。

用 netcat 扮演客户端,运行结果如下:

$ nc 127.0.0.1 2013
2011-02-02 03:31:26.622647    # 服务器返回的时间字符串

time
Time 协议与 daytime 极为类似,只不过它返回的不是日期时间字符串,而是一个 32-bit 整数,表示从 1970-01-01 00:00:00Z 到现在的秒数。当然,这个协议有“2038 年问题”。服务端只需要关注“三个半事件”中的“连接已建立”事件,事件处理函数如下:

   1: void TimeServer::onConnection(const muduo::net::TcpConnectionPtr& conn)   2: {   3:   LOG_INFO << "TimeServer - " << conn->peerAddress().toHostPort() << " -> "   4:     << conn->localAddress().toHostPort() << " is "   5:     << (conn->connected() ? "UP" : "DOWN");   6:   if (conn->connected())   7:   {   8:     int32_t now = sockets::hostToNetwork32(static_cast<int>(::time(NULL)));   9:     conn->send(&now, sizeof now);  // 发送 4 个字节  10:     conn->shutdown();  // 主动断开连接  11:   }  12: }剩下的都是例行公事的代码,为节省篇幅,此处从略,请阅读 muduo/examples/易做图/time。

用 netcat 扮

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,