• <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年4月>
            272829303112
            3456789
            10111213141516
            17181920212223
            24252627282930
            1234567

            導航

            統計

            常用鏈接

            隨筆分類

            隨筆檔案

            相冊

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            91精品久久久久久无码| 亚洲国产另类久久久精品| 无码国产69精品久久久久网站| 91久久香蕉国产熟女线看| 午夜精品久久久久久毛片| 久久久久国产精品嫩草影院| 久久精品国产色蜜蜜麻豆| 久久久91人妻无码精品蜜桃HD| 国产91久久综合| 2021国产成人精品久久| 国内精品久久久久国产盗摄| 色综合久久精品中文字幕首页| 久久精品国产91久久麻豆自制| 久久99国产精品久久久| 精品国产婷婷久久久| 久久青青草原亚洲av无码| 亚洲精品NV久久久久久久久久| 亚洲国产日韩欧美久久| 伊人久久大香线蕉综合Av| 99精品久久精品一区二区| 国产成人无码精品久久久久免费| 久久久久亚洲精品无码网址| 人妻无码精品久久亚瑟影视| 麻豆AV一区二区三区久久| 久久A级毛片免费观看| 国产AV影片久久久久久| 伊人久久无码精品中文字幕| 久久亚洲私人国产精品vA | 久久国产精品久久精品国产| 亚洲嫩草影院久久精品| 日韩久久无码免费毛片软件| 漂亮人妻被黑人久久精品| 国产综合精品久久亚洲| 国内高清久久久久久| 色综合久久精品中文字幕首页| 国产精品久久婷婷六月丁香| 国内精品久久久久影院一蜜桃| 久久精品国产72国产精福利| 色综合久久综合中文综合网| 久久av高潮av无码av喷吹| 久久久久久久97|