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

Muduo網絡編程示例之四:Twisted Finger

編輯:關於C語言

 1 拒絕連接
什麼都不做,程序空等。finger01.cc

   1: #include    2:     3: using namespace muduo;   4: using namespace muduo::net;   5:     6: int main()   7: {   8:   EventLoop loop;   9:   loop.loop();  10: }
2 接受新連接
在 1079 端口偵聽新連接,接受連接之後什麼都不做,程序空等。muduo 會自動丟棄收到的數據。finger02.cc

   1: #include    2: #include    3:     4: using namespace muduo;   5: using namespace muduo::net;   6:     7: int main()   8: {   9:   EventLoop loop;  10:   TcpServer server(&loop, InetAddress(1079), "Finger");  11:   server.start();  12:   loop.loop();  13: }
3 主動斷開連接
接受新連接之後主動斷開。finger03.cc

以下省略頭文件和 namespace。

   1: void onConnection(const TcpConnectionPtr& conn)   2: {   3:   if (conn->connected())   4:   {   5:     conn->shutdown();   6:   }   7: }   8:     9: int main()  10: {  11:   EventLoop loop;  12:   TcpServer server(&loop, InetAddress(1079), "Finger");  13:   server.setConnectionCallback(onConnection);  14:   server.start();  15:   loop.loop();  16: }
4 讀取用戶名,然後斷開連接
如果讀到一行以 結尾的消息,就斷開連接。finger04.cc

注意這段代碼有安全問題,如果惡意客戶端不斷發送數據而不換行,會撐爆服務端的內存。另外,Buffer::findCRLF() 是線性查找,如果客戶端每次發一個字節,服務端的時間復雜度為 O(N^2),會消耗 CPU 資源。

   1: void onMessage(const TcpConnectionPtr& conn,   2:                Buffer* buf,   3:                Timestamp receiveTime)   4: {   5:   if (buf->findCRLF())   6:   {   7:     conn->shutdown();   8:   }   9: }  10:    11: int main()  12: {  13:   EventLoop loop;  14:   TcpServer server(&loop, InetAddress(1079), "Finger");  15:   server.setMessageCallback(onMessage);  16:   server.start();  17:   loop.loop();  18: }
5. 讀取用戶名、輸出錯誤信息、然後斷開連接
如果讀到一行以 結尾的消息,就發送一條出錯信息,然後斷開連接。finger05.cc

安全問題同上。

   1: void onMessage(const TcpConnectionPtr& conn,   2:                Buffer* buf,   3:                Timestamp receiveTime)   4: {   5:   if (buf->findCRLF())   6:   {   7:     conn->send("No such user ");   8:     conn->shutdown();   9:   }  10: }  11:    12: int main()  13: {  14:   EventLoop loop;  15:   TcpServer server(&loop, InetAddress(1079), "Finger");  16:   server.setMessageCallback(onMessage);  17:   server.start();  18:   loop.loop();  19: }
6. 從空的 UserMap 裡查找用戶
從一行消息中拿到用戶名(第 22 行),在 UserMap 裡查找,然後返回結果。finger06.cc

安全問題同上。

   1: typedef std::map UserMap;   2: UserMap users;   3:     4: string getUser(const string& user)   5: {   6:   string result = "No such user";   7:   UserMap::iterator it = users.find(user);   8:   if (it != users.end())   9:   {  10:     result = it->second;  11:   }  12:   return result;  13: }  14:    15: void onMessage(const TcpConnectionPtr& conn,  16:                Buffer* buf,  17:                Timestamp receiveTime)  18: {  19:   const char* crlf = buf->findCRLF();  20:   if (crlf)  21:   {  22:     string user(buf->peek(), crlf);  23:     conn->send(getUser(user) + " ");  24:     buf->retrieveUntil(crlf + 2);  25:     conn->shutdown();  26:   }  27: }  28:    29: int main()  30: {  31:   EventLoop loop;  32:   TcpServer server(&loop, InetAddress(1079), "Finger");  33:   server.setMessageCallback(onMessage);  34:   server.start();  35:   loop.loop();  36: }
7. 往 UserMap 裡添加一個用戶
與前面幾乎完全一樣,只多了第 31 行。finger07.cc

   1: typedef std::map UserMap;   2: UserMap users;   3:     4: string getUser(const string& user)   5: {   6:   string result = "No such user";   7:   UserMap::iterator it = users.find(user);   8:   if (it != users.end())   9:   {  10:     result = it->second;  11:   }  12:   return result;  13: }  14:    15: void onMessage(const TcpConnectionPtr& conn,  16:                Buffer* buf,  17:                Timestamp receiveTime)  18: {  19:   const char* crlf = buf->findCRLF();  20:   if (crlf)  21:   {  22:     string user(buf->peek(), crlf);  23:     conn->send(getUser(user) + " ");  24:     buf->retrieveUntil(crlf + 2);  25:     conn->shutdown();  26:   }  27: }  28:    29: int main()  30: {  31:   users["schen"] = "Happy and well";  32:   EventLoop loop;  33:   TcpServer server(&loop, InetAddress(1079), "Finger");  34:   server.setMessageCallback(onMessage);  35:   server.start();  36:   loop.loop();  37: }
以上就是全部內容,可以用 telnet 扮演客戶端來測試我們的簡單 finger 服務端。

Telnet 測試
在一個命令行窗口運行

$ ./bin/twisted_finger07

另一個命令行運行

$ telnet localhost 1079
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is ^].
muduo
No such user
Connection closed by foreign host.

再試一次

$ telnet localhost 1079
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is ^].
schen
Happy and well
Connection closed by foreign host.


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