• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            陳碩的Blog

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

            陳碩 (giantchen_AT_gmail)

            Blog.csdn.net/Solstice

            這是《Muduo 網絡編程示例》系列的第四篇文章。

            Muduo 全系列文章列表: http://blog.csdn.net/Solstice/category/779646.aspx

            Python Twisted 是一款非常好的網絡庫,它也采用 Reactor 作為網絡編程的基本模型,所以從使用上與 muduo 頗有相似之處。(當然,muduo 沒有 deferreds)Finger 是 twisted 文檔的一個經典例子,本文展示如何用 muduo 來實現最簡單的 finger 服務端。限于篇幅,只實現 finger01~07。代碼位于 examples/twisted/finger

            1 拒絕連接

            什么都不做,程序空等。finger01.cc

               1: #include <muduo/net/EventLoop.h>
               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 <muduo/net/EventLoop.h>
               2: #include <muduo/net/TcpServer.h>
               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 讀取用戶名,然后斷開連接

            如果讀到一行以 \r\n 結尾的消息,就斷開連接。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. 讀取用戶名、輸出錯誤信息、然后斷開連接

            如果讀到一行以 \r\n 結尾的消息,就發送一條出錯信息,然后斷開連接。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\r\n");
               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<string, string> 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) + "\r\n");
              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<string, string> 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) + "\r\n");
              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.

            冒煙測試過關。

            (待續)

            posted on 2011-02-23 21:33 陳碩 閱讀(2381) 評論(0)  編輯 收藏 引用 所屬分類: muduo

            <2011年2月>
            303112345
            6789101112
            13141516171819
            20212223242526
            272812345
            6789101112

            導航

            統計

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            色偷偷88888欧美精品久久久| 国产精品伊人久久伊人电影 | 久久久久久无码Av成人影院| 国产精品久久新婚兰兰| 无码国产69精品久久久久网站| 久久久久亚洲AV无码专区体验 | 亚洲狠狠久久综合一区77777 | 亚洲AV无码久久寂寞少妇| 粉嫩小泬无遮挡久久久久久| 日韩电影久久久被窝网| 国产精品久久久久无码av| 久久久精品久久久久特色影视| 亚洲性久久久影院| 亚洲精品美女久久777777| 国产毛片久久久久久国产毛片 | 久久婷婷是五月综合色狠狠| 国产一区二区三区久久| 久久人人爽人人人人爽AV | 国产精品久久午夜夜伦鲁鲁| 伊人久久一区二区三区无码| 久久国产精品99国产精| 久久久久久久综合狠狠综合| 精品水蜜桃久久久久久久| 国产精品美女久久久久| 色综合久久久久无码专区| 三级片免费观看久久| 久久国产免费| 天天久久狠狠色综合| 国产一久久香蕉国产线看观看| 日本人妻丰满熟妇久久久久久| 香蕉久久AⅤ一区二区三区| 久久久久无码专区亚洲av| segui久久国产精品| 精品一区二区久久| 久久99热狠狠色精品一区| 日产精品久久久久久久| 欧美熟妇另类久久久久久不卡 | 久久久艹| 久久天天婷婷五月俺也去 | 青青青国产成人久久111网站| a级成人毛片久久|