程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Muduo網絡編程示例之一:五個簡單 TCP 協議

Muduo網絡編程示例之一:五個簡單 TCP 協議

編輯:關於C語言

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/simple/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/simple/time。

用 netcat 扮

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved