青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

陳碩的Blog

Muduo 網絡編程示例之零:前言

陳碩 (giantchen_AT_gmail)

Blog.csdn.net/Solstice

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

我將會寫一系列文章,介紹用 muduo 網絡庫完成常見的 TCP 網絡編程任務。目前計劃如下:

  1. UNP 中的簡單協議,包括 echo、daytime、time、discard 等。 
  2. Boost.Asio 中的示例,包括 timer2~6、chat 等。
  3. Java Netty 中的示例,包括 discard、echo、uptime 等,其中的 discard 和 echo 帶流量統計功能。
  4. Python twisted 中的示例,包括 finger01~07
  5. 云風的串并轉換連接服務器 multiplexer,包括單線程和多線程兩個版本。
  6. 用于測試兩臺機器的往返延遲的 roundtrip
  7. 用于測試兩臺機器的帶寬的 pingpong
  8. 文件傳輸
  9. 一個基于 TCP 的應用層廣播 hub
  10. socks4a 代理服務器,包括簡單的 TCP 中繼(relay)。
  11. 一個 Sudoku 服務器的演變,從單線程到多線程,從阻塞到 event-based。
  12. 一個提供短址服務的 httpd 服務器

其中前面 7 個已經放到了 muduo 代碼的 examples 目錄中,下載地址是: http://muduo.googlecode.com/files/muduo-0.1.5-alpha.tar.gz 

這些例子都比較簡單,邏輯不復雜,代碼也很短,適合摘取關鍵部分放到博客上。其中一些有一定的代表性與針對性,比如“如何傳輸完整的文件”估計是網絡編程的初學者經常遇到的問題。請注意,muduo 是設計來開發內網的網絡程序,它沒有做任何安全方面的加強措施,如果用在公網上可能會受到攻擊,在后面的例子中我會談到這一點。

本系列文章適用于 Linux 2.6.x (x > 25),主要測試發行版為 Ubuntu 10.04 LTSDebian 6.0 Squeeze,64-bit x86 硬件。

TCP 網絡編程本質論

我認為,TCP 網絡編程最本質的是處理三個半事件:

  1. 連接的建立,包括服務端接受 (accept) 新連接和客戶端成功發起 (connect) 連接。
  2. 連接的斷開,包括主動斷開 (close 或 shutdown) 和被動斷開 (read 返回 0)。
  3. 消息到達,文件描述符可讀。這是最為重要的一個事件,對它的處理方式決定了網絡編程的風格(阻塞還是非阻塞,如何處理分包,應用層的緩沖如何設計等等)。
  4. 消息發送完畢,這算半個。對于低流量的服務,可以不必關心這個事件;另外,這里“發送完畢”是指將數據寫入操作系統的緩沖區,將由 TCP 協議棧負責數據的發送與重傳,不代表對方已經收到數據。

這其中有很多難點,也有很多細節需要注意,比方說:

  1. 如果要主動關閉連接,如何保證對方已經收到全部數據?如果應用層有緩沖(這在非阻塞網絡編程中是必須的,見下文),那么如何保證先發送完緩沖區中的數據,然后再斷開連接。直接調用 close(2) 恐怕是不行的。
  2. 如果主動發起連接,但是對方主動拒絕,如何定期 (帶 back-off) 重試?
  3. 非阻塞網絡編程該用邊沿觸發(edge trigger)還是電平觸發(level trigger)?(這兩個中文術語有其他譯法,我選擇了一個電子工程師熟悉的說法。)如果是電平觸發,那么什么時候關注 EPOLLOUT 事件?會不會造成 busy-loop?如果是邊沿觸發,如何防止漏讀造成的饑餓?epoll 一定比 poll 快嗎?
  4. 在非阻塞網絡編程中,為什么要使用應用層緩沖區?假如一次讀到的數據不夠一個完整的數據包,那么這些已經讀到的數據是不是應該先暫存在某個地方,等剩余的數據收到之后再一并處理?見 lighttpd 關于 \r\n\r\n 分包的 bug。假如數據是一個字節一個字節地到達,間隔 10ms,每個字節觸發一次文件描述符可讀 (readable) 事件,程序是否還能正常工作?lighttpd 在這個問題上出過安全漏洞
  5. 在非阻塞網絡編程中,如何設計并使用緩沖區?一方面我們希望減少系統調用,一次讀的數據越多越劃算,那么似乎應該準備一個大的緩沖區。另一方面,我們系統減少內存占用。如果有 10k 個連接,每個連接一建立就分配 64k 的讀緩沖的話,將占用 640M 內存,而大多數時候這些緩沖區的使用率很低。muduo 用 readv 結合棧上空間巧妙地解決了這個問題。
  6. 如果使用發送緩沖區,萬一接收方處理緩慢,數據會不會一直堆積在發送方,造成內存暴漲?如何做應用層的流量控制?
  7. 如何設計并實現定時器?并使之與網絡 IO 共用一個線程,以避免鎖。

這些問題在 muduo 的代碼中可以找到答案。

Muduo 簡介

我編寫 Muduo 網絡庫的目的之一就是簡化日常的 TCP 網絡編程,讓程序員能把精力集中在業務邏輯的實現上,而不要天天和 Sockets API 較勁。借用 Brooks 的話說,我希望 Muduo 能減少網絡編程中的偶發復雜性 (accidental complexity)。

Muduo 只支持 Linux 2.6.x 下的并發非阻塞 TCP 網絡編程,它的安裝方法見陳碩的 blog 文章

Muduo 的使用非常簡單,不需要從指定的類派生,也不用覆寫虛函數,只需要注冊幾個回調函數去處理前面提到的三個半事件就行了。

以經典的 echo 回顯服務為例:

1. 定義 EchoServer class,不需要派生自任何基類:

 

 1 #ifndef MUDUO_EXAMPLES_SIMPLE_ECHO_ECHO_H 
 2 #define MUDUO_EXAMPLES_SIMPLE_ECHO_ECHO_H
 3 
 4 #include <muduo/net/TcpServer.h>
 5 
 6 // RFC 862 
 7 class EchoServer 
 8 
 9 public
10   EchoServer(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_ECHO_ECHO_H
27 

 

在構造函數里注冊回調函數:

 

 1 EchoServer::EchoServer(EventLoop* loop, 
 2                        const InetAddress& listenAddr) 
 3   : loop_(loop), 
 4     server_(loop, listenAddr, "EchoServer"
 5 
 6   server_.setConnectionCallback( 
 7       boost::bind(&EchoServer::onConnection, this, _1)); 
 8   server_.setMessageCallback( 
 9       boost::bind(&EchoServer::onMessage, this, _1, _2, _3)); 
10 }
11 
12 void EchoServer::start() 
13 
14   server_.start(); 
15 
16 
17 

 

2. 實現 EchoServer::onConnection() 和 EchoServer::onMessage():

 

 1 void EchoServer::onConnection(const TcpConnectionPtr& conn) 
 2 
 3   LOG_INFO << "EchoServer - " << conn->peerAddress().toHostPort() << " -> " 
 4     << conn->localAddress().toHostPort() << " is " 
 5     << (conn->connected() ? "UP" : "DOWN"); 
 6 }
 7 
 8 void EchoServer::onMessage(const TcpConnectionPtr& conn, 
 9                            Buffer* buf, 
10                            Timestamp time) 
11 
12   string msg(buf->retrieveAsString()); 
13   LOG_INFO << conn->name() << " echo " << msg.size() << " bytes at " << time.toString(); 
14   conn->send(msg); 
15 }
16 

 

3. 在 main() 里用 EventLoop 讓整個程序跑起來:

 

 1 #include "echo.h"
 2 
 3 #include <muduo/base/Logging.h> 
 4 #include <muduo/net/EventLoop.h>
 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(2007); 
14   EchoServer server(&loop, listenAddr); 
15   server.start(); 
16   loop.loop(); 
17 }
18 

 

完整的代碼見 muduo/examples/simple/echo。
這個幾十行的小程序實現了一個并發的 echo 服務程序,可以同時處理多個連接。
對這個程序的詳細分析見下一篇博客《Muduo 網絡編程示例之一:五個簡單 TCP 協議》

(待續)

posted on 2011-02-02 01:07 陳碩 閱讀(9392) 評論(0)  編輯 收藏 引用 所屬分類: muduo

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

導航

統計

常用鏈接

隨筆分類

隨筆檔案

相冊

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            麻豆精品传媒视频| 亚洲无线观看| 午夜精品美女自拍福到在线| 国产精品草草| 亚洲欧美精品在线| 小嫩嫩精品导航| 欧美一区视频| 免费黄网站欧美| 欧美人与性动交cc0o| 欧美三级乱人伦电影| 国产女精品视频网站免费| 国外成人网址| 亚洲人成在线播放| 亚洲最新在线| 午夜精品久久久久久久久| 欧美一级大片在线观看| 噜噜噜91成人网| 亚洲精品在线观看免费| 亚洲欧美在线免费观看| 老鸭窝毛片一区二区三区| 欧美另类视频在线| 国产欧美日韩综合| 最新成人在线| 久久日韩精品| 正在播放日韩| 卡通动漫国产精品| 国产精品久久久久久妇女6080| 狠狠综合久久| 亚洲欧美另类国产| 亚洲成人资源| 亚洲精品国久久99热| 欧美在线免费观看| 欧美大片在线观看| 国语精品一区| 亚洲一区二区三区精品视频| 牛牛国产精品| 久久er99精品| 欧美日韩亚洲激情| 亚洲日韩中文字幕在线播放| 亚久久调教视频| 亚洲国产美女久久久久| 久久久久久久久综合| 国产精品视频久久一区| 一区二区三区高清| 欧美高清在线一区二区| 久久久99国产精品免费| 国产精品视频网址| 亚洲一区二区三区色| 亚洲福利精品| 久久裸体艺术| 国产欧美一区二区视频| 亚洲欧美日本日韩| 亚洲精选中文字幕| 欧美精选午夜久久久乱码6080| 在线观看国产日韩| 久久只有精品| 久久欧美中文字幕| 激情伊人五月天久久综合| 久久精品视频免费| 午夜久久影院| 国产一区在线免费观看| 欧美日韩精品福利| 国产午夜亚洲精品不卡| 欧美一区精品| 亚洲欧美日韩国产成人精品影院 | 一区二区三区不卡视频在线观看 | 99精品视频一区| 亚洲激情影视| 欧美激情综合亚洲一二区| 亚洲精品日韩在线| 日韩午夜中文字幕| 国产精品激情偷乱一区二区∴| 亚洲一区精品视频| 亚洲影视综合| 韩国精品一区二区三区| 蜜臀av性久久久久蜜臀aⅴ四虎| 美女爽到呻吟久久久久| 一区二区三区国产在线| 亚洲理论在线| 国产老女人精品毛片久久| 久久亚洲不卡| 欧美精品一区二区三区在线播放 | 久久免费观看视频| 亚洲成人在线网| 亚洲乱码国产乱码精品精可以看 | 欧美中文字幕久久| 性久久久久久久久久久久| 亚洲成人影音| 最新热久久免费视频| 国产精品久久久久久久久久直播| 亚洲欧美自拍偷拍| 久久久久国产精品厨房| 日韩一级在线| 香蕉久久夜色精品| 日韩小视频在线观看| 亚洲欧美在线看| 日韩亚洲精品电影| 久久国产精品久久w女人spa| 亚洲精品免费观看| 欧美一区免费视频| 99国产精品久久久久久久| 亚洲在线观看免费| 亚洲免费电影在线| 久久精选视频| 午夜亚洲伦理| 欧美日韩黄色大片| 免费试看一区| 国产深夜精品| aa日韩免费精品视频一| 亚洲成人资源| 久久国产精品网站| 亚洲免费一区二区| 国产欧美日韩亚洲| 亚洲精品一区二区三区在线观看| 国产精品网红福利| 99re国产精品| 亚洲精品美女| 蜜臀av国产精品久久久久| 久久久国产一区二区| 国产精品嫩草99av在线| 亚洲乱码久久| 亚洲精品麻豆| 欧美福利一区二区| 欧美成年人视频网站| 狠狠色狠狠色综合| 亚洲欧美综合另类中字| 香蕉久久夜色精品| 国产精品久久久久久久午夜| 亚洲欧洲在线播放| 日韩午夜视频在线观看| 欧美激情一区二区三区蜜桃视频| 欧美高清视频一区二区三区在线观看| 黄色国产精品| 久久青青草综合| 理论片一区二区在线| 国产亚洲精品一区二555| 午夜精品电影| 久久久国产亚洲精品| 狠狠色伊人亚洲综合网站色| 久久久精品2019中文字幕神马| 久久国产精品99久久久久久老狼| 国产伦精品一区二区三区四区免费| 亚洲永久字幕| 久久资源在线| 最新中文字幕一区二区三区| 男男成人高潮片免费网站| 欧美护士18xxxxhd| 亚洲免费电影在线观看| 欧美日韩一区二区三区视频 | 午夜精品短视频| 久久精品免费观看| 亚洲高清视频在线观看| 欧美激情精品久久久久久蜜臀| 亚洲精品在线电影| 欧美一区二区三区男人的天堂| 国产一区二区三区四区五区美女| 久久精品成人| 亚洲高清视频在线| 亚洲免费影院| 在线电影国产精品| 欧美韩日一区二区| 亚洲欧美日韩精品久久久久| 久久午夜羞羞影院免费观看| 亚洲日韩中文字幕在线播放| 欧美午夜片在线观看| 欧美亚洲免费在线| 亚洲国产精品福利| 午夜激情综合网| 国产综合一区二区| 欧美日韩成人精品| 欧美主播一区二区三区| 亚洲精品欧洲精品| 久久免费黄色| 亚洲性图久久| 91久久精品国产91久久性色tv| 国产精品社区| 欧美激情aⅴ一区二区三区| 91久久久久久久久| 久久精品国产清自在天天线| 亚洲肉体裸体xxxx137| 国产乱码精品1区2区3区| 久久亚洲综合| 欧美激情精品久久久久久免费印度| 国产精品色一区二区三区| 久久精品2019中文字幕| 999在线观看精品免费不卡网站| 久久激情网站| 亚洲午夜日本在线观看| 91久久精品一区二区别| 国产夜色精品一区二区av| 久久午夜精品| 亚洲欧美日韩视频一区| 一区二区三区高清在线观看| 欧美国产日韩视频| 久久久久久网站| 欧美中文字幕第一页| 亚洲天堂av在线免费观看| 亚洲黄网站在线观看| 国际精品欧美精品| 国产日韩av在线播放|