• <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>
            隨筆-167  評論-8  文章-0  trackbacks-0

            1.     SocketServer.py

            1.1  整體結構

            在基類中調用并不實現的方法;類似于C++的純虛函數,強迫派生類實現。不一樣的是,如果派生類中不調用(派生類的用戶也不調用)該方法,那么派生類就可以不實現這個方法。

            對某些函數提供一個空的實現,相當于JAVA的Adapter類,提供一個缺省實現。

            RequestHandler的使用。并不是提供一個虛或者純虛函數來處理網絡請求,而是通過一個Handler類(或者函數,或者其它任何可以被調用的東西)來進行處理。

            這就是傳說中的Strategy 模式。

            優點:處理網絡請求和監聽、接受網絡請求相分離;松散耦合;無論哪個模塊都更容易重用。

            MixIn的結構更加優雅。

            1.2  BaseServer結構

            可以被調用,不能被覆蓋的函數:

            Ø         __init__(server_address, RequestHandlerClass)
            在 Base 中構造函數,保存 address 和 handler class,不調用任何函數。
            在TCP中,構造 socket 對象,調用 server_bind和server_activate。

            Ø         serve_forever()
            循環處理每一個請求,直到世界末日 while True: self.handle_request()
            在 TCP中沒有覆蓋

            在 UDP 中沒有覆蓋

            Ø         handle_request()  # if you do not use serve_forever()
            處理一個請求,在處理過程中,有可能產生阻塞。首先調用 get_request 獲得一個請求;然后調用verify_request對請求進行驗證;如果驗證成功,調用process_request對請求進行處理;如果處理過程中發生錯誤,調用handl_error處理錯誤,調用close_request釋放資源。
              try:

                        request, client_address = self.get_request()

                    except socket.error:

                        return

                    if self.verify_request(request, client_address):

                        try:

                            self.process_request(request, client_address)

                        except:

                            self.handle_error(request, client_address)

                          self.close_request(request)

            在 TCP 中沒有覆蓋
            在 UDP 中沒有覆蓋

            Ø         fileno() -> int   # for select()
            在 BaseServer中沒有實現
            在 TCP 中調用 socket.fileno
            在 UDP 中沒有覆蓋

             

            可以被覆蓋的函數

            Ø         server_bind()
            在 Base 中沒有實現
            在 TCP 中調用 socket.bind
            在 UDP 中沒有覆蓋

            Ø         server_activate()
            在 Base 中沒有實現
            在 TCP 中調用 socket.listen
            在 UDP 中實現為空函數

            Ø         get_request() -> request, client_address
            在 BaseServer 中沒有實現
            在 TCP 中調用 socket.accept
            在 UDP 中調用 socket.recvfrom

            Ø         verify_request(request, client_address)
            在 Base 中實現為空函數
            在 TCP 中沒有覆蓋

            Ø         server_close()
            清理 server 所占用的資源,可以被覆蓋。
            在 Base 中實現為空函數
            在TCP中調用 socket.close
            在 UDP 中沒有覆蓋

            Ø         process_request(request, client_address)
            在 Base中調用 finish_request,然后 close_request。
            在 TCP 中沒有覆蓋
            在 UDP 中沒有覆蓋

            Ø         close_request(request)
            清理 request 所占用的資源,可以被覆蓋
            在 Base 中實現為空函數
            在 TCP 中調用 socket.close
            在 UDP 中實現為空函數

            Ø         handle_error()
            在 Base 中打印錯誤信息。
            在 TCP 中沒有覆蓋
            在 UDP 中沒有覆蓋

            向派生類提供的函數:

            Ø         finish_request(request, client_address)
            在 Base 中通過構造一個 RequestHandlerClass 實例來完成對request 的處理。
            在 TCP 中沒有覆蓋
            在 UDP 中沒有覆蓋

            1.3  MixIn結構

            為 Base Server 提供多線程和多進程支持。

            1.3.1           ForkingMinxIn提供多進程支持

            在列表active_children中保存最大數量為max_children的進程。

            在process_request中調用collect_children,檢查進程數量是否達到限制。如果進程數量達到限制,需要等待一個進程退出后,才會處理新請求。

            在處理新的請求時,通過os.fork創建一個新進程:

            1.        父進程
            將子進程的oid加入active_children;調用close_request

            2.        子進程
            調用finish_request,如果發生錯誤,調用handle_error

            1.3.2           ThreadingMixIn提供多線程支持

            在process_request中創建新線程,在新線程中調用finish_request和close_request。支持daemon線程。

            1.3.3           通過繼承使用

            通過繼承某個MixIn和Server來達到目的。其中MixIn是第一基類,而Server是第二基類。MixIn中的process_request覆蓋Server的process_request。

            1.4  RequestHandler結構

            在BaseRequestHandler中有如下四個函數:

            Ø         __init__,構造函數
            保存request, client_address, server;依次調用 setup, handle, finish。
            這是一個Temeplate Method Pattern,派生類不能覆蓋。
            如果派生類要提供自己的構造函數,就應該不使用BaseRequestHandler提供的處理模式。

            Ø         setup,空函數

            Ø         handle,空函數,處理請求

            Ø         finish,空函數

            在派生類StreamRequestHandler中:

            Ø         覆蓋setup
            根據request(對于TCP來說應該是socket對象)構造read file和
            write file
            這樣派生類可以直接使用rfile和wfile進行數據讀寫

            Ø         覆蓋finish
            對輸出文件調用flush;關閉兩個文件對象

            在派生類DatagramRequestHandler中:

            Ø         覆蓋setup
            將輸入流通過StringIO方法封裝成read file;構造一個空的輸出流StringIO() write file

            Ø         覆蓋finish
            將輸出流中的數據發送到client_address

            優點:無論是stream還是datagram方式,通過分別從這兩個類派生,都可以直接使用rfile和wfile進行數據讀寫。

             


            posted on 2009-08-04 16:45 老馬驛站 閱讀(453) 評論(0)  編輯 收藏 引用 所屬分類: python
            久久综合精品国产一区二区三区| 久久亚洲精品中文字幕| 久久成人国产精品一区二区| 久久久久久久国产免费看| yy6080久久| 国产精品丝袜久久久久久不卡 | 久久人妻少妇嫩草AV蜜桃| 婷婷五月深深久久精品| 国产精品欧美亚洲韩国日本久久| 伊人久久精品无码二区麻豆| 亚洲国产成人久久综合碰碰动漫3d | 99久久综合狠狠综合久久止| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 亚洲国产精品无码久久一区二区 | 色偷偷888欧美精品久久久| 香蕉aa三级久久毛片| 久久久九九有精品国产| 一本大道久久香蕉成人网| 久久99国产精品久久| 亚洲国产成人精品91久久久| 7国产欧美日韩综合天堂中文久久久久 | 一本色道久久99一综合| 国产成人无码精品久久久免费| 狠狠色婷婷久久综合频道日韩 | 久久国产色AV免费看| 日本五月天婷久久网站| 久久强奷乱码老熟女网站| 色欲av伊人久久大香线蕉影院| 久久久WWW成人免费毛片| 亚洲嫩草影院久久精品| 久久国产高清字幕中文| 久久国产免费观看精品3| 亚洲中文字幕无码久久综合网| 欧美久久久久久午夜精品| 91精品国产综合久久香蕉 | 久久综合视频网站| 久久久久久久亚洲精品| 久久久久亚洲爆乳少妇无 | 久久精品国产免费| 99久久精品久久久久久清纯| 国产精品久久久久影院嫩草|