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

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運轉,開心的工作
            簡單、開放、平等的公司文化;尊重個性、自由與個人價值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理
            spserver 是一個實現了半同步/半異步(Half-Sync/Half-Async)和領導者/追隨者(Leader/Follower) 模式的服務器框架,能夠簡化 TCP server 的開發工作。
            spserver 使用 c++ 實現,目前實現了以下功能:
            1.封裝了 TCP server 中接受連接的功能;
            2.使用非阻塞型I/O和事件驅動模型,由主線程負責處理所有 TCP 連接上的數據讀取和發送,因此連接數不受線程數的限制;
            3.主線程讀取到的數據放入隊列,由一個線程池處理實際的業務。
            4.一個 http 服務器框架,即嵌入式 web 服務器(請參考:
            SPWebServer:一個基于 SPServer 的 web 服務器框架

            0.6 版本之前只包含 Half-Sync/Half-Async 模式的實現,0.6 版本開始包含 Leader/Follower 模式的實現
            0.7 版本開始支持 ssl 。把 socket 相關的操作抽象為一個 IOChannel 層,關于 openssl 的部分單獨實現為一個 plugin 的形式,對于不使用 ssl 功能的用戶,不需要引入 ssl 相關的頭文件和庫。
            0.7.5 增加了一個 sptunnel 程序,是一個通用的 ssl proxy 。類似 stunnel 。
            0.9.0 移植 spserver 到 windows 平臺,需要在 windows 下編譯 libevent 和 pthread 。
            0.9.1 在 windows 平臺,去掉了對 libevent 和 pthread 依賴,完全使用 iocp 和 windows 的線程機制實現了半同步半異步的框架。
            0.9.2 移植了所有的功能到 windows 平臺,同時新增加了 xyssl 的插件。

            主頁:
            http://code.google.com/p/spserver/

            源代碼下載:
            http://spserver.googlecode.com/files/spserver-0.6.src.tar.gz
            http://code.google.com/p/spserver/downloads/list


            在實現并發處理多事件的應用程序方面,有如下兩種常見的編程模型:
            ThreadPerConnection的多線程模型和事件驅動的單線程模型。

            ThreadPerConnection的多線程模型
            優點:簡單易用,效率也不錯。在這種模型中,開發者使用同步操作來編寫程序,比如使用阻塞型I/O。使用同步操作的程序能夠隱式地在線程的運行堆棧中維護應用程序的狀態信息和執行歷史,方便程序的開發。
            缺點:沒有足夠的擴展性。如果應用程序只需處理少量的并發連接,那么對應地創建相應數量的線程,一般的機器都還能勝任;但如果應用程序需要處理成千上萬個連接,那么為每個連接創建一個線程也許是不可行的。

            事件驅動的單線程模型
            優點:擴展性高,通常性能也比較好。在這種模型中,把會導致阻塞的操作轉化為一個異步操作,主線程負責發起這個異步操作,并處理這個異步操作的結果。由于所有阻塞的操作都轉化為異步操作,理論上主線程的大部分時間都是在處理實際的計算任務,少了多線程的調度時間,所以這種模型的性能通常會比較好。
            缺點:要把所有會導致阻塞的操作轉化為異步操作。一個是帶來編程上的復雜度,異步操作需要由開發者來顯示地管理應用程序的狀態信息和執行歷史。第二個是目前很多廣泛使用的函數庫都很難轉為用異步操作來實現,即是可以用異步操作來實現,也將進一步增加編程的復雜度。

            并發系統通常既包含異步處理服務,又包含同步處理服務。系統程序員有充分的理由使用異步特性改善性能。相反,應用程序員也有充分的理由使用同步處理簡化他們的編程強度。

            針對這種情況,ACE 的作者提出了 半同步/半異步 (Half-Sync/Half-Async) 模式。
            引用

            《POSA2》上對這個模式的描述如下:
            半同步/半異步 體系結構模式將并發系統中的異步和同步服務處理分離,簡化了編程,同時又沒有降低性能。該模式介紹了兩個通信層,一個用于異步服務處理,另一個用于同步服務處理。

            目標:
            需要同步處理的簡易性的應用程序開發者無需考慮異步的復雜性。同時,必須將性能最大化的系統開發者不需要考慮同步處理的低效性。讓同步和異步處理服務能夠相互通信,而不會使它們的編程模型復雜化或者過度地降低它們的性能。

            解決方案:
            將系統中的服務分解成兩層,同步和異步,并且在它們之間增加一個排隊層協調異步和同步層中的服務之間的通信。在獨立線程或進程中同步地處理高層服務(如耗時長的數據庫查詢或文件傳輸),從而簡化并發編程。相反,異步地處理底層服務(如從網絡連接上讀取數據),以增強性能。如果駐留在相互獨立的同步和異步層中的服務必須相互通信或同步它們的處理,則應允許它們通過一個排隊層向對方傳遞消息。

            模式原文:Half-Sync/Half-Async: An Architectural Pattern for Efficient and Well-structured Concurrent I/O
            http://www.cs.wustl.edu/~schmidt/PDF/HS-HA.pdf
            中文翻譯:http://blog.chinaunix.net/u/31756/showart_245841.html

            如果上面關于 半同步/半異步 的說明過于抽象,那么可以看一個《POSA2》中提到的例子:
            許多餐廳使用 半同步/半異步 模式的變體。例如,餐廳常常雇傭一個領班負責迎接顧客,并在餐廳繁忙時留意給顧客安排桌位,為等待就餐的顧客按序排隊是必要的。領班由所有顧客“共享”,不能被任何特定顧客占用太多時間。當顧客在一張桌子入坐后,有一個侍應生專門為這張桌子服務。




            下面來看一個使用 spserver 實現的簡單的 line echo server 。

            Java代碼 復制代碼
            1. class?SP_EchoHandler?:?public?SP_Handler?{ ??
            2. public: ??
            3. ??SP_EchoHandler(){} ??
            4. ??virtual?~SP_EchoHandler(){} ??
            5. ??
            6. ??//?return?-1?:?terminate?session,?0?:?continue ??
            7. ??virtual?int?start(?SP_Request?*?request,?SP_Response?*?response?)?{ ??
            8. ????request->setMsgDecoder(?new?SP_LineMsgDecoder()?); ??
            9. ????response->getReply()->getMsg()->append( ??
            10. ??????"Welcome?to?line?echo?server,?enter?'quit'?to?quit.\r\n"?); ??
            11. ??
            12. ????return?0;??? ??
            13. ??}????? ??
            14. ??
            15. ??//?return?-1?:?terminate?session,?0?:?continue ??
            16. ??virtual?int?handle(?SP_Request?*?request,?SP_Response?*?response?)?{ ??
            17. ????SP_LineMsgDecoder?*?decoder?=?(SP_LineMsgDecoder*)request->getMsgDecoder(); ??
            18. ??
            19. ????if(?0?!=?strcasecmp(?(char*)decoder->getMsg(),?"quit"?)?)?{ ??
            20. ??????response->getReply()->getMsg()->append(?(char*)decoder->getMsg()?); ??
            21. ??????response->getReply()->getMsg()->append(?"\r\n"?); ??
            22. ??????return?0;????????? ??
            23. ????}?else?{???? ??
            24. ??????response->getReply()->getMsg()->append(?"Byebye\r\n"?); ??
            25. ??????return?-1;???????? ??
            26. ????}??????????? ??
            27. ??}????? ??
            28. ??virtual?void?error(?SP_Response?*?response?)?{} ??
            29. ??
            30. ??virtual?void?timeout(?SP_Response?*?response?)?{} ??
            31. ??
            32. ??virtual?void?close()?{} ??
            33. }; ??
            34. ??
            35. class?SP_EchoHandlerFactory?:?public?SP_HandlerFactory?{ ??
            36. public: ??
            37. ??SP_EchoHandlerFactory()?{} ??
            38. ??virtual?~SP_EchoHandlerFactory()?{} ??
            39. ??
            40. ??virtual?SP_Handler?*?create()?const?{ ??
            41. ????return?new?SP_EchoHandler(); ??
            42. ??} ??
            43. }; ??
            44. ??
            45. int?main(?int?argc,?char?*?argv[]?) ??
            46. { ??
            47. ??int?port?=?3333; ??
            48. ??
            49. ??SP_Server?server(?"",?port,?new?SP_EchoHandlerFactory()?); ??
            50. ??server.runForever(); ??
            51. ??
            52. ??return?0; ??
            53. }??


            在最簡單的情況下,使用 spserver 實現一個 TCP server 需要實現兩個類:SP_Handler 的子類 和 SP_HandlerFactory 的子類。
            SP_Handler 的子類負責處理具體業務。
            SP_HandlerFactory 的子類協助 spserver 為每一個連接創建一個 SP_Handler 子類實例。

            1.SP_Handler 生命周期
            SP_Handler 和 TCP 連接一對一,SP_Handler 的生存周期和 TCP 連接一樣。
            當 TCP 連接被接受之后,SP_Handler 被創建,當 TCP 連接斷開之后,SP_Handler將被 destroy。

            2.SP_Handler 函數說明
            SP_Handler 有 5 個純虛方法需要由子類來重載。這 5 個方法分別是:
            start:當一個連接成功接受之后,將首先被調用。返回 0 表示繼續,-1 表示結束連接。
            handle:當一個請求包接收完之后,將被調用。返回 0 表示繼續,-1 表示結束連接。
            error:當在一個連接上讀取或者發送數據出錯時,將被調用。error 之后,連接將被關閉。
            timeout:當一個連接在約定的時間內沒有發生可讀或者可寫事件,將被調用。timeout 之后,連接將被關閉。
            close:當一個 TCP 連接被關閉時,無論是正常關閉,還是因為 error/timeout 而關閉。

            3.SP_Handler 函數調用時機
            當需要調用 SP_Handler 的 start/handle/error/timeout 方法時,相關的參數將被放入隊列,然后由線程池來負責執行 SP_Handler 對應的方法。因此在 start/handle/error/timeout 中可以使用同步操作來編程,可以直接使用阻塞型 I/O 。
            在發生 error 和 timeout 事件之后,close 緊跟著這兩個方法之后被調用。
            如果是程序正常指示結束連接,那么在主線程中直接調用 close 方法。

            4.高級功能--MsgDecoder
            這個 line echo server 比起常見的 echo server 有一點不同:只有在讀到一行時才進行 echo。
            這個功能是通過一個稱為 MsgDecoder 的接口來實現的。不同的 TCP server 在應用層的傳輸格式上各不相同。
            比如在 SMTP/POP 這一類的協議中,大部分命令是使用 CRLF 作為分隔符的。而在 HTTP 中是使用 Header + Body 的形式。
            為了適應不同的 TCP server,在 spserver 中有一個 MsgDecoder 接口,用來處理這些應用層的協議。
            比如在這個 line echo server 中,把傳輸協議定義為:只有讀到一行時將進行 echo 。
            那么相應地就要實現一個 SP_LineMsgDecoder ,這個 LineMsgDecoder 負責判斷目前的輸入緩沖區中是否已經有完整的一行。

            MsgDecoder 的接口如下:

            Java代碼 復制代碼
            1. class?SP_MsgDecoder?{ ??
            2. public: ??
            3. ??virtual?~SP_MsgDecoder(); ??
            4. ??
            5. ??enum?{?eOK,?eMoreData?}; ??
            6. ??virtual?int?decode(?SP_Buffer?*?inBuffer?)?=?0; ??
            7. };??


            decode 方法對 inBuffer 里面的數據進行檢查,看是否符合特定的要求。如果已經符合要求,那么返回 eOK ;如果還不滿足要求,那么返回 eMoreData。比如 LineMsgDecoder 的 decode 方法的實現為:

            Java代碼 復制代碼
            1. int?SP_LineMsgDecoder?::?decode(?SP_Buffer?*?inBuffer?) ??
            2. {??????????????? ??
            3. ??if(?NULL?!=?mLine?)?free(?mLine?); ??
            4. ??mLine?=?inBuffer->getLine(); ??
            5. ???????? ??
            6. ??return?NULL?==?mLine???eMoreData?:?eOK; ??
            7. }?????


            spserver 默認提供了幾個 MsgDecoder 的實現:
            SP_DefaultMsgDecoder :它的 decode 總是返回 eOK ,即只要有輸入就當作是符合要求了。
            ??? 如果應用不設置 SP_Request->setMsgDecoder 的話,默認使用這個。
            SP_LineMsgDecoder : 檢查到有一行的時候,返回 eOK ,按行讀取輸入。
            SP_DotTermMsgDecoder :檢查到輸入中包含了特定的 <CRLF>.<CRLF> 時,返回 eOK。

            具體的使用例子可以參考示例:testsmtp 。

            5.高級功能--實現聊天室
            spserver 還提供了一個廣播消息的功能。使用消息廣播功能可以方便地實現類似聊天室的功能。具體的實現可以參考示例:testchat 。

            6.libevent
            spserver 使用 c++ 實現,使用了一個第三方庫--libevent,以便在不同的平臺上都能夠使用最有效的事件驅動機制(Currently, libevent supports /dev/poll, kqueue(2), select(2), poll(2) and epoll(4). )。
            91精品国产综合久久久久久| 日韩AV毛片精品久久久| 久久久久无码精品| 精品无码人妻久久久久久| 99久久久精品免费观看国产| 思思久久精品在热线热| 一本一道久久a久久精品综合| 精品综合久久久久久88小说| 精品久久久久久99人妻| 久久久久国色AV免费观看| 欧美亚洲另类久久综合婷婷| 色综合合久久天天给综看| 一本久久a久久精品综合香蕉| 日韩中文久久| 人妻丰满AV无码久久不卡| 国产午夜精品久久久久免费视 | 精品久久久久久久久中文字幕| 日产精品久久久一区二区| 国产精品久久国产精麻豆99网站| 精品蜜臀久久久久99网站| 91秦先生久久久久久久| 亚洲伊人久久综合影院| 亚洲中文字幕无码久久2017| 久久精品国产一区| 久久久久久免费视频| 996久久国产精品线观看| 久久高清一级毛片| 天天躁日日躁狠狠久久| 国产精品久久久99| 色综合久久综合中文综合网| 99久久精品免费观看国产| 久久久久99这里有精品10 | 日产精品99久久久久久| 国产福利电影一区二区三区,免费久久久久久久精 | 一级a性色生活片久久无| AV狠狠色丁香婷婷综合久久 | 日日狠狠久久偷偷色综合96蜜桃| 国内精品综合久久久40p| 久久精品18| 久久精品国产精品青草app| 精品国产99久久久久久麻豆|