1. 程式人生 > >socketserver模塊使用方法

socketserver模塊使用方法

isp class add over 必須 執行過程 open dtc t對象

一、socketserver模塊介紹

Python提供了兩個基本的socket模塊。一個是socket,它提供了標準的BSD Socket API; 另一個是socketserver,它提供了服務器中心類,可以簡化網絡服務器的開發

socketserver

socketserver內部使用IO多路復用以及“多線程”和“多進程”,從而實現並發處理多個客戶端請求的socket服務端。 即,每個客服端請求連接到服務器時,socket服務端都會在服務器上創建一個“線程”或“進程”專門負責處理當前客戶端的所有請求。

二、socketserver中的ThreadingTCPServer類

ThreadingTCPServer實現的socket服務器內部會為每個client創建一個“線程”,該線程用來和客戶端就行交互 ThreadingTCPServer源碼內容:

class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass


#可以看到ThreadTCPServer類本身並沒有方法,而是繼承了(ThreadingMinIn, TCPServer) 這兩個類。 而TCPServer則是繼承了BaseServer類。

三、ThreadingTCPServer的使用方法

1、創建一個繼承socketserver.BaseRequestHandler的類

2、類中必須重寫一個名為handler的方法

3、實例化一個服務器類,傳入服務器的地址和請求處理程序類

4、調用serve_forever()事件循環監聽

技術分享圖片
#!/usr/bin/env python3
import socketserver

class Handler(socketserver.BaseRequestHandler):    # 必須繼承BaseRequestHandler
    def handle(self):        # 必須有handle方法
        print(New connection:,self.client_address)
        while True:
            data = self.request.recv(1024)
            if not data:break
print(Client data:,data.decode()) self.request.send(data) if __name__ == __main__: server = socketserver.ThreadingTCPServer((127.0.0.1,8009),Handler) # 實例化對象,實現多線程的socket server.serve_forever() # 事件監聽,並調用handler方法
View Code

四、ThreadingTCPServer執行過程

1、啟動服務端程序

2、執行TCPServer.__init__方法,創建服務端socket對象並綁定IP和端口(根據類的繼承關系,即查找順序找到TCPServer.__init__())

3、執行BaseServer.__init__方法,將自定義的繼承自socketserver.BaseRequestHandler的類MyRequestHandler賦值給self.RequestHandlerClass class TCPServer(BaseServer): #(繼承了BaseServeer類)

技術分享圖片
class TCPServer(BaseServer): #(繼承了BaseServeer類)
    def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):
        """Constructor.  May be extended, do not override."""
        BaseServer.__init__(self, server_address, RequestHandlerClass)  #(重寫了BaseServer的__init__方法)
        self.socket = socket.socket(self.address_family,
                                    self.socket_type)
        if bind_and_activate:
            try:
                self.server_bind()
                self.server_activate()
            except:
                self.server_close()
                raise

class BaseServer:
    def __init__(self, server_address, RequestHandlerClass):  #(接收了兩個傳進來的參數)
        """Constructor.  May be extended, do not override."""
        self.server_address = server_address
        self.RequestHandlerClass = RequestHandlerClass     #(賦值給了self.RequestHandlerClass)
        self.__is_shut_down = threading.Event()
        self.__shutdown_request = False
View Code

4、通過實例化的對象,執行serve_forever方法,該方法首先查找到BaseServer下的方法,通過調用selector模塊,註冊事件監聽對象,並執行_handle_request_noblock方法 找到此方法,並調用該方法下的process_request方法,在此調用到finish_request方法,通過finish_request方法,執行了RequestHandlerClass方法,執行此方法就相當於調用 了我們重寫的Handler類。

技術分享圖片
class BaseServer:
    def serve_forever(self, poll_interval=0.5):
        try:
            with _ServerSelector() as selector:
                selector.register(self, selectors.EVENT_READ)

                while not self.__shutdown_request:
                    ready = selector.select(poll_interval)
                    if ready:
                        self._handle_request_noblock()

                    self.service_actions()
   def _handle_request_noblock(self):
        try:
            request, client_address = self.get_request()
        except OSError:
            return
        if self.verify_request(request, client_address):
            try:
                self.process_request(request, client_address)
            except Exception:
                self.handle_error(request, client_address)
                self.shutdown_request(request)
            except:
                self.shutdown_request(request)
                raise
        else:
            self.shutdown_request(request)
    def process_request(self, request, client_address):
        self.finish_request(request, client_address)
        self.shutdown_request(request)
    def finish_request(self, request, client_address):
        self.RequestHandlerClass(request, client_address, self)
View Code

5、通過Handler類實例化對象,調用繼承的BaseRequestHandler類中的__init__方法,並執行了handler方法。 從而運行了我們重寫Handler類中的handler方法。

技術分享圖片
class BaseRequestHandler:
    def __init__(self, request, client_address, server):
        self.request = request
        self.client_address = client_address
        self.server = server
        self.setup()
        try:
            self.handle()   #調用handler()
        finally:
            self.finish()
View Code

五、調用流程圖

技術分享圖片

socketserver模塊使用方法