Python探索之SocketServer詳解
SocketServer,網(wǎng)絡(luò)通信服務(wù)器,是Python標(biāo)準(zhǔn)庫(kù)中的一個(gè)模塊,其作用是創(chuàng)建網(wǎng)絡(luò)服務(wù)器。SocketServer模塊定義了一些類(lèi)來(lái)處理諸如TCP、UDP、UNIX流和UNIX數(shù)據(jù)報(bào)之上的同步網(wǎng)絡(luò)請(qǐng)求。
SocketServer模塊處理網(wǎng)絡(luò)請(qǐng)求的功能,可以通過(guò)兩個(gè)主要的類(lèi)來(lái)實(shí)現(xiàn):一個(gè)是服務(wù)器類(lèi),一個(gè)是請(qǐng)求處理類(lèi)。
服務(wù)器類(lèi) 處理通信問(wèn)題,如監(jiān)聽(tīng)一個(gè)套接字并接收連接等;
請(qǐng)求處理類(lèi) 處理“協(xié)議”問(wèn)題,如解釋到來(lái)的數(shù)據(jù)、處理數(shù)據(jù)并把數(shù)據(jù)發(fā)回給客戶端等。
這種實(shí)現(xiàn)將服務(wù)器的實(shí)現(xiàn)過(guò)程和請(qǐng)求處理的實(shí)現(xiàn)過(guò)程解耦,這意味著我們可以將不同的服務(wù)器實(shí)現(xiàn)和請(qǐng)求處理實(shí)現(xiàn)結(jié)合起來(lái)來(lái)處理一些定制的協(xié)議,例如一個(gè)TCP服務(wù)器類(lèi)和一個(gè)流請(qǐng)求處理類(lèi)結(jié)合,處理基于TCP的網(wǎng)絡(luò)請(qǐng)求。同時(shí),也可以基于SocketServer模塊中的服務(wù)器類(lèi)和請(qǐng)求處理類(lèi),實(shí)現(xiàn)網(wǎng)絡(luò)層之上應(yīng)用層的服務(wù)器和請(qǐng)求處理實(shí)現(xiàn),例如基于TCP服務(wù)器類(lèi)實(shí)現(xiàn)HTTP服務(wù)器,基于流處理請(qǐng)求類(lèi)實(shí)現(xiàn)HTTP請(qǐng)求處理類(lèi)等。
服務(wù)器類(lèi)
SocketServer模塊中定義了五種服務(wù)器類(lèi)。
BaseServer(服務(wù)器的基類(lèi),定義了API)
TCPServer(使用TCP/IP套接字)
UDPServer(使用數(shù)據(jù)報(bào)套接字)
UnixStreamServer(使用UNIX域套接字,只適用UNIX平臺(tái))
UnixDatagramServer(使用UNIX域套接字,只適用UNIX平臺(tái))
1. 構(gòu)造服務(wù)器對(duì)象
要構(gòu)建一個(gè)服務(wù)器對(duì)象,需要向它傳遞一個(gè)地址server_address(服務(wù)器將在這個(gè)地址上監(jiān)聽(tīng)請(qǐng)求),以及一個(gè)請(qǐng)求處理類(lèi)RequestHandlerClass(不是請(qǐng)求處理實(shí)例)。服務(wù)器類(lèi)基類(lèi)的構(gòu)造函數(shù)如下:
class BaseServer: def __init__(self, server_address, RequestHandlerClass): """Constructor. May be extended, do not override.""" self.server_address = server_address self.RequestHandlerClass = RequestHandlerClass self.__is_shut_down = threading.Event() self.__shutdown_request = False
后,可以構(gòu)造TCPServer、UDPServer、UnixStreamServer、UnixDatagramServer。其中,TCPServer繼承自BaseServer,UDPServer和UnixStreamServer繼承自TCPServer,UnixDatagramServer繼承自UDPServer。各個(gè)服務(wù)器類(lèi)型可以根據(jù)自己的特點(diǎn)對(duì)基類(lèi)進(jìn)行擴(kuò)展,例如創(chuàng)建監(jiān)聽(tīng)套接字、綁定監(jiān)聽(tīng)地址和端口、進(jìn)行監(jiān)聽(tīng)等。一旦實(shí)例化服務(wù)器對(duì)象,便可以使用服務(wù)器的方法來(lái)監(jiān)聽(tīng)和處理請(qǐng)求。
2. 實(shí)現(xiàn)服務(wù)器
由于SocketServer模塊中定義的五種服務(wù)器類(lèi)中,除了基類(lèi)BaseServer和TCPServer外,其余的三個(gè)類(lèi)都是直接或間接地繼承自TCPServer。因此,以下以TCPServer的實(shí)現(xiàn)過(guò)程為例進(jìn)行說(shuō)明。
構(gòu)造TCPServer。 構(gòu)造TCPServer時(shí),構(gòu)造函數(shù)創(chuàng)建了一個(gè)套接字(這個(gè)套接字可以通過(guò)更改地址簇和類(lèi)型用于其他服務(wù)器)用于監(jiān)聽(tīng)請(qǐng)求。并且調(diào)用server_bind()綁定監(jiān)聽(tīng)的地址和端口,調(diào)用server_activate()開(kāi)始監(jiān)聽(tīng)。
啟動(dòng)服務(wù)器。 服務(wù)器實(shí)例化后,可以使用serve_forever()或者h(yuǎn)andle_request()來(lái)監(jiān)聽(tīng)和處理請(qǐng)求,實(shí)現(xiàn)服務(wù)器功能。這兩個(gè)方法的具體實(shí)現(xiàn)依賴于_handle_request_noblock()方法。這個(gè)方法是BaseServer類(lèi)中定義的。具體實(shí)現(xiàn)如下:
def _handle_request_noblock(self): """Handle one request, without blocking. I assume that select.select has returned that the socket is readable before this function was called, so there should be no risk of blocking in get_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.shutdown_request(request) else: self.shutdown_request(request)
處理請(qǐng)求。 根據(jù)上一步驟啟動(dòng)服務(wù)器后,服務(wù)器便開(kāi)始監(jiān)聽(tīng)請(qǐng)求。如果接收到請(qǐng)求信息,便開(kāi)始處理請(qǐng)求。由_handle_request_noblock()可以看出有幾個(gè)函數(shù)比較重要。
get_request() ——這個(gè)函數(shù)可以在子類(lèi)中重寫(xiě)。在TCPServer中,該函數(shù)調(diào)用監(jiān)聽(tīng)套接字的accept()方法,返回請(qǐng)求request和客戶端地址client_address。
verify_request(request, client_address) ——這個(gè)函數(shù)可以在子類(lèi)中重寫(xiě)。該函數(shù)返回True表示處理請(qǐng)求,返回False表示忽略請(qǐng)求。
process_request(request, client_address) ——這個(gè)函數(shù)可以在子類(lèi)中重寫(xiě)。該函數(shù)將調(diào)用finish_request()具體完成請(qǐng)求的處理過(guò)程,并且在處理完請(qǐng)求后關(guān)閉請(qǐng)求。
finish_request(request, client_address) ——該函數(shù)將構(gòu)造一個(gè)請(qǐng)求處理類(lèi)的實(shí)例。請(qǐng)求處理類(lèi)被實(shí)例化后將調(diào)用其handle()方法處理請(qǐng)求。
3. 進(jìn)程/線程支持
SocketServer模塊中還提供了一些”mix-in”類(lèi):ForkingMixIn和ThreadingMixIn。這些類(lèi)可以和服務(wù)器類(lèi)混合使用,很容易改變服務(wù)器,為每個(gè)請(qǐng)求使用一個(gè)單獨(dú)的進(jìn)程或線程。具體的服務(wù)器類(lèi)有:
class ForkingUDPServer(ForkingMixIn, UDPServer)
class ForkingTCPServer(ForkingMixIn, TCPServer)
class ThreadingUDPServer(ThreadingMixIn, UDPServer)
class ThreadingTCPServer(ThreadingMixIn, TCPServer)
class ThreadingUnixStreamServer(ThreadingMixIn, UnixStreamServer)
class ThreadingUnixDatagramServer(ThreadingMixIn, UnixDatagramServer)
請(qǐng)求處理類(lèi)
要接收到來(lái)的請(qǐng)求以及確定采取什么行動(dòng),其中大部分的工作都是由請(qǐng)求處理類(lèi)完成的。請(qǐng)求處理類(lèi)負(fù)責(zé)在套接字層之上實(shí)現(xiàn)協(xié)議。具體過(guò)程為:讀取請(qǐng)求、處理請(qǐng)求、寫(xiě)回響應(yīng)。請(qǐng)求處理類(lèi)基類(lèi)中定義了3個(gè)方法,子類(lèi)中需要重寫(xiě)。
setup() ——為請(qǐng)求準(zhǔn)備請(qǐng)求處理器
handle() ——對(duì)請(qǐng)求完成具體的工作。諸如解析到來(lái)的請(qǐng)求,處理數(shù)據(jù),并發(fā)回響應(yīng)等。
finish() ——清理setup()期間創(chuàng)建的所有數(shù)據(jù)
總結(jié)
以上就是本文關(guān)于Python探索之SocketServer詳解的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:Python探索之URL Dispatcher實(shí)例詳解、Bottle框架中的裝飾器類(lèi)和描述符應(yīng)用詳解等,如有不足之處,歡迎留言指出。感謝朋友們對(duì)本站的支持!
- Python使用socketServer包搭建簡(jiǎn)易服務(wù)器過(guò)程詳解
- python網(wǎng)絡(luò)編程:socketserver的基本使用方法實(shí)例分析
- 基于python socketserver框架全面解析
- 利用Python中SocketServer 實(shí)現(xiàn)客戶端與服務(wù)器間非阻塞通信
- Python使用SocketServer模塊編寫(xiě)基本服務(wù)器程序的教程
- 實(shí)例講解Python中SocketServer模塊處理網(wǎng)絡(luò)請(qǐng)求的用法
- python網(wǎng)絡(luò)編程之TCP通信實(shí)例和socketserver框架使用例子
- Python網(wǎng)絡(luò)編程之socket與socketserver
相關(guān)文章
python使用pywinauto驅(qū)動(dòng)微信客戶端實(shí)現(xiàn)公眾號(hào)爬蟲(chóng)
這個(gè)項(xiàng)目是通過(guò)pywinauto控制windows(win10)上的微信PC客戶端來(lái)實(shí)現(xiàn)公眾號(hào)文章的抓取。代碼分成server和client兩部分。server接收client抓取的微信公眾號(hào)文章,并且保存到數(shù)據(jù)庫(kù)。另外server支持簡(jiǎn)單的搜索和導(dǎo)出功能。client通過(guò)pywinauto實(shí)現(xiàn)微信公眾號(hào)文章的抓取。2021-05-05Python?Tkinter?Gui運(yùn)行不卡頓(解決多線程解決界面卡死問(wèn)題)
最近寫(xiě)的Python代碼不知為何,總是執(zhí)行到一半卡住不動(dòng),所以下面這篇文章主要給大家介紹了關(guān)于Python?Tkinter?Gui運(yùn)行不卡頓,解決多線程解決界面卡死問(wèn)題的相關(guān)資料,需要的朋友可以參考下2023-02-02Python中使用第三方庫(kù)xlrd來(lái)寫(xiě)入Excel文件示例
這篇文章主要介紹了Python中使用第三方庫(kù)xlrd來(lái)寫(xiě)入Excel文件示例,本文講解了安裝xlwt、API介紹、使用xlwt寫(xiě)入Excel文件實(shí)例,需要的朋友可以參考下2015-04-04Pandas根據(jù)條件實(shí)現(xiàn)替換列中的值
在使用Pandas的Python中,DataFrame列中的值可以通過(guò)使用各種內(nèi)置函數(shù)根據(jù)條件進(jìn)行替換,本文主要來(lái)和大家討論在Pandas中用條件替換數(shù)據(jù)集列中的值的各種方法,希望對(duì)大家有所幫助2024-01-01PyCharm活動(dòng)模板設(shè)置步驟實(shí)現(xiàn)
很多情況,我們?cè)趯?xiě)代碼都會(huì)存在經(jīng)常要寫(xiě)一些簡(jiǎn)單且又重復(fù)的代碼,Pycharm中的活動(dòng)模板可以把這些使用頻率很高的一些代碼打包起來(lái)設(shè)置一個(gè)快捷鍵,本文就來(lái)介紹一下如何實(shí)現(xiàn)2023-12-12python如何派生內(nèi)置不可變類(lèi)型并修改實(shí)例化行為
這篇文章主要為大家詳細(xì)介紹了python如何派生內(nèi)置不可變類(lèi)型并修改實(shí)例化行為,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03