• <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 陳碩 閱讀(2390) 評論(0)  編輯 收藏 引用 所屬分類: muduo

            <2010年8月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234

            導航

            統計

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            26uuu久久五月天| 久久久久亚洲AV成人网人人软件| 精品视频久久久久| 热综合一本伊人久久精品| 久久影视国产亚洲| 人妻无码久久一区二区三区免费 | 久久国产亚洲精品无码| 成人亚洲欧美久久久久| 岛国搬运www久久| 色婷婷噜噜久久国产精品12p| 亚洲伊人久久综合影院| 亚洲精品视频久久久| 久久婷婷五月综合色奶水99啪| 伊人久久综合无码成人网| 精品永久久福利一区二区| 久久久精品国产亚洲成人满18免费网站| 久久99精品久久久久久齐齐| 久久亚洲精品国产精品| 中文精品久久久久人妻| 久久线看观看精品香蕉国产| 国内高清久久久久久| 久久AAAA片一区二区| 丁香狠狠色婷婷久久综合| 狠狠综合久久AV一区二区三区| 久久九九兔免费精品6| 久久久久亚洲AV成人网人人软件| 久久综合给合久久狠狠狠97色 | 一本久久综合亚洲鲁鲁五月天亚洲欧美一区二区 | 久久99热只有频精品8| 狠狠精品久久久无码中文字幕| 国产91久久综合| 久久久国产一区二区三区| 青青草原1769久久免费播放| 色婷婷综合久久久久中文| 亚洲va中文字幕无码久久| 久久婷婷色香五月综合激情| 久久精品视频免费| 国产精品视频久久久| 久久99国产精品二区不卡| A级毛片无码久久精品免费| 精品国产乱码久久久久软件|