• <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>

            loop_in_codes

            低調做技術__歡迎移步我的獨立博客 codemaro.com 微博 kevinlynx

            剖析Etwork網絡庫

            Author : Kevin Lynx

            從開始接觸網絡編程這個東西開始,我就不間斷地閱讀一些網絡庫(模塊)的源代碼,主要目的是為了獲取別
            人在這方面的經驗,編程這東西,還是要多實踐啊。

            基本上,Etwork是一個很小巧的網絡庫。Etwork基于select模型,采用我之前說的技巧,理論上可以處理很
            多連接(先不說效率)。

            先看看下這個庫的結構:

            classgraph

            如同很多網絡庫一樣,總會有一個類似于ISocketManager的類,用于管理所有網絡連接(當用戶服務器時)。
            而ISocket則用于代表一個網絡連接。在其他庫中,ISocketManager對應的可能就是Server,而ISocket對應
            的則是Session。

            在接口設計上,盡管Etwork寫了很多接口類(看看那些IClass),但是事實上它抽象得并不徹底。只是暴露給
            客戶端的代碼很簡潔,而庫本身依然臃腫。不知道為什么,現在我比較喜歡純C這種簡潔的東西,對于OO以及
            template,漸漸地有點心累。

            在功能實現上,我以TCP服務器為例,CreateEtwork根據傳來的參數建立服務器,在SocketManager::open中
            是很常規的socket, bind, listen。當建立了服務器之后,需要在程序主循環里不斷地輪詢狀態,這里主要
            調用poll函數完成。

            poll函數主體就是調用select。當select成功返回活動的套接字數量后,Etwork依次輪詢讀、寫、錯誤fdset,
            將保存的所有網絡連接(就是那些ISocket對象)對應的套接字與fdset中當前的套接字做比較。大致邏輯為:

            fd_count = select( 0, readset, writeset, exceptset, &timeout ); 

            for( each fd in readset )
                
            if( fd is listening fd ) 
                    accept 
            new connection
                
            else
                    
            for( each socket in all connections )
                        
            if( fd == socket )
                            can read data on 
            this socket 

            for( each fd in writeset )
             

            for( each fd in exceptset )
             


            沒什么特別讓人注意的地方(別覺得別人垃圾,耐心讀別人的代碼不是什么壞事)。每一次,當Etwork檢測到
            新的連接時,會創建新的ISocket對象,并關聯對應的套接字,然后保存此對象到一個列表中。當poll結束
            后,客戶端程序通常會調用accept函數(Etwork中提供的接口),該函數主要是將poll中保存的新的ISocket
            對象全部拷貝出去。

            在接收、發送網絡數據上,Etwork如同幾乎所有的網絡庫(模塊)一樣,采用了緩沖機制。這里所說的緩沖機
            制是,網絡模塊接收到網絡數據時,將數據保存起來,客戶端程序想獲取數據時,實際上就是從這個緩沖中
            直接取,而不是從網絡上獲取;同理,發送數據時,客戶端程序將數據提供給網絡模塊,網絡模塊將數據保
            存起來,網絡模塊會在另一個時候發送這個緩沖中的數據(對于異步IO的處理畢竟不一樣)。

            Etwork關于這個緩沖機制的相關代碼,主要集中在Buffer這個類。與Buffer相關的是一個Message機制。Buffer
            維護了一個Message的隊列(deque)。一個Message實際上是一個非常簡單的結構體:

             

            struct Message 
            {
                unsigned 
            short offset_;
                unsigned 
            short size_;
            }

             

            這其實是消息頭,在消息頭后全部是數據。在創建消息時(new_message),Etwork根據客戶端提供的數據創建
            足夠大的緩存保存:

             

            Message * m = (Message *)::operator new( size + sizeof( Message ) ); 

             

            這其實是一個很危險的做法,但是從Etwokr的源碼可以看出來,作者很喜歡玩弄這個技巧。與Buffer具體相
            關的接口包括:get_data, put_data, get_message, put_message。Buffer內部維護的數據都是以Message
            的形式組織。但是,對于外部而言,卻依然是raw data,也就是諸如char*之類的數據。幾個相關函數大致
            上的操作為:獲取指定尺寸的消息(可能包含多個消息),將一段數據加入Buffer并以消息的形式組織(可能會
            創建多個消息),將一個消息以raw data的形式輸出,將raw data以一個消息的形式加入到Buffer。

            一般情況下,Etwork的poll操作,會將套接字上的數據接收并put_data到緩沖中;發送數據時則get_data。
            客戶端要從緩沖中獲取數據時,就調用get_message;發送數據時就put_message。

            Etwork中還有一個比較有趣的東西:marshaller。這個東西主要就是提供將C++中各種數據類型的變量進行字
            節編碼,也就是將int long struct之類的東西轉換為unsigned char,從而方便直接往網絡上發送。

            基本上,Buffer和marshaller可以說是一個網絡庫(模塊)的必要部件,你可以在不同的網絡庫中看到類似的
            東西。

            Etwork在網絡事件的處理上,除了上面的輪詢外,還支持回調機制。這主要是通過INotify,以及給各個ISocket
            注冊Notify對象實現。沒什么難度,基本上就是observer模式的簡單實現。

            其他東西就沒什么好說的了,縱觀一下,Etwork實現得還是比較典型的,可以作為開發網絡庫的一個簡單例子。

            posted on 2008-05-21 21:06 Kevin Lynx 閱讀(6995) 評論(5)  編輯 收藏 引用 所屬分類: network

            評論

            # re: 剖析Etwork網絡庫 2008-05-21 21:52 空明流轉

            做面向對象大抵就是兩個極端,一個是回歸過程化的抽象,一個就是純面向對象。

            不過感覺這個傾向是跟你長期從事的領域有關。  回復  更多評論   

            # re: 剖析Etwork網絡庫 2008-05-21 23:04 eXile

            我也是越來越不喜歡C++了,目前比較傾向于純C或Python。
            對于純C的網絡庫,可以試試 libevent 或 libev, 應該算是比較好的庫了。  回復  更多評論   

            # re: 剖析Etwork網絡庫 2008-05-22 10:42 關中刀客

            很多時候底層還是自己寫比較的好~~~  回復  更多評論   

            # re: 剖析Etwork網絡庫 2008-05-22 17:56 bugs_killer

            ACE設計得就很好啊..我基于ACE裁剪過一個輕型的通信庫.
            http://code.google.com/p/netdkit/

            自我感覺很好啊.  回復  更多評論   

            # re: 剖析Etwork網絡庫 2009-09-29 10:47 libev

            libev是網絡庫?@eXile
              回復  更多評論   

            超级碰久久免费公开视频| 无码人妻久久一区二区三区免费 | 久久精品99无色码中文字幕| 99久久婷婷国产综合精品草原| 久久av高潮av无码av喷吹| 久久精品国产乱子伦| 久久亚洲国产欧洲精品一| 少妇熟女久久综合网色欲| 99久久免费国产精品热| 久久久久这里只有精品| 久久这里只有精品18| 久久午夜无码鲁丝片午夜精品| 久久青青草原精品国产| 久久久久国色AV免费看图片| 精品人妻久久久久久888| 伊人色综合九久久天天蜜桃| 久久九九亚洲精品| 新狼窝色AV性久久久久久| 久久中文字幕视频、最近更新| .精品久久久麻豆国产精品| 久久无码中文字幕东京热| 久久精品无码一区二区三区日韩| 亚洲国产精品无码久久SM| 中文字幕亚洲综合久久菠萝蜜| 9191精品国产免费久久| 久久精品午夜一区二区福利| 国产欧美久久久精品影院| 伊人久久大香线蕉综合网站| 久久久精品人妻无码专区不卡| 99久久免费国产精品| 一本伊大人香蕉久久网手机| 成人久久精品一区二区三区| 99国产欧美精品久久久蜜芽| 国产精品久久国产精品99盘| 99久久人妻无码精品系列| 久久99精品久久久久子伦| 久久香综合精品久久伊人| 久久A级毛片免费观看| 久久精品国产亚洲av麻豆色欲| 亚洲AV无码成人网站久久精品大| 久久综合亚洲色一区二区三区|