SocketServer源码学习(二)
SocketServer 中非常重要的兩個基類就是:BaseServer 和 BaseRequestHandler
在SocketServer 中也提供了對TCP以及UDP的高級封裝,這次我們主要通過分析關于TCP的處理邏輯來對SocketServer模塊進行一個很好的理解和學習
TCPServer
TCPServer 繼承了BaseServer,初始化的時候,進行了socket套接字的創建。
def __init__(self, server_address, RequestHandlerClass, bind_and_activate=True):"""Constructor. May be extended, do not override."""BaseServer.__init__(self, server_address, RequestHandlerClass)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在這里我們看到了我們非常熟悉的關于socket的創建的內容:
self.socket = socket.socket(self.address_family, self.socket_type)
通過socket模塊創建了socket對象,接著調用了server_bind和server_activate
server_bind
源碼內容如下:
def server_bind(self):"""Called by constructor to bind the socket.May be overridden."""if self.allow_reuse_address:self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)self.socket.bind(self.server_address)self.server_address = self.socket.getsockname()這里我們看到了非常熟悉的操作socket.bind方法,以及設置了socket的相關屬性
server_activate
源碼內容如下:
def server_activate(self):"""Called by constructor to activate the server.May be overridden."""self.socket.listen(self.request_queue_size)同樣的這里的調用也非常簡單就是執行了socket.listen
get_request
在TCPServer類中我們還看到了get_request方法,源碼內容如下:
def get_request(self):"""Get the request and client address from the socket.May be overridden."""return self.socket.accept()這個的調用其實我們可以在BaseServer這個基類中看到,我們之前看過關于BaseServer中這個基類的源碼
我們可以從我們調用BaseServer基類中的serve_forever方法查看,這里是調用了_handle_request_noblock方法,我繼續查看_handle_request_noblock這個源碼
可以看到這里最后是調用了process_request來處理請求,繼續查看源碼:
def process_request(self, request, client_address):"""Call finish_request.Overridden by ForkingMixIn and ThreadingMixIn."""self.finish_request(request, client_address)self.shutdown_request(request)def finish_request(self, request, client_address):"""Finish one request by instantiating RequestHandlerClass."""self.RequestHandlerClass(request, client_address, self)從上面的代碼我們可以到最后是在finish_request中實例化了RequestHandlerClass
我們 這個時候查看一下BaseRequestHandler這個基類的源碼如下:
在初始化函數里我們看到了調用setup()方法,這setup在StreamRequestHandler會被重寫
StreamRequestHandler
TCPServer實現了使用tcp套接字的網絡服務,Handler方面則是對應的StreamRequestHandler。它繼承了BaseRequestHandler。基類的setup方法和finish方法被它重寫,用于通過連接實現緩存文件的讀寫操作。
setup方法
源碼內容如下:
def setup(self):self.connection = self.requestif self.timeout is not None:self.connection.settimeout(self.timeout)if self.disable_nagle_algorithm:self.connection.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY, True)self.rfile = self.connection.makefile('rb', self.rbufsize)self.wfile = self.connection.makefile('wb', self.wbufsize)這里主要設置了對應連接的屬性,其中創建了兩個對象非常重要:
一個可讀(rfile)和一個可寫(wfile)的“文件”對象
但是實際并不是創建了文件,而是封裝了讀取數據和發送數據的操作,抽象成了對文件的操作
可以理解:
self.rfile 就是讀取客戶端數據的對象,它有一些方法可以讀取數據。self.wfile則是用來發送數據給客戶端的對象。
整理流程(TCP)
實現TCP服務需要使用TCPServer和StreamRequestHandler共同協作
?
轉載于:https://www.cnblogs.com/zhaof/p/8890600.html
總結
以上是生活随笔為你收集整理的SocketServer源码学习(二)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宏杉科技 难忘十年
- 下一篇: vscode 遇到的迷之bug nvm