日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

使用Python SocketServer快速实现多线程网络服务器

發(fā)布時(shí)間:2023/12/15 python 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用Python SocketServer快速实现多线程网络服务器 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Python SocketServer使用介紹

1、簡介:

?????????SocketServer是python的一個(gè)網(wǎng)絡(luò)服務(wù)器框架,可以減少開發(fā)人員編寫網(wǎng)絡(luò)服務(wù)器程序的工作量。

? ? ? ? ?SocketServer總共有4個(gè)server基類。

? ? ? ? ?TCPServer:負(fù)責(zé)處理TCP協(xié)議。

? ? ? ? ?UDPServer:負(fù)責(zé)處理UDP協(xié)議。

? ? ? ? ?UnixStreamServer:只適用于類unix平臺,不常用。

? ? ? ? ?UnixDatagramServer:只適用于類unix平臺,不常用。

? ? ? ? ?這4個(gè)類會同步處理每一個(gè)request,也就是說只有當(dāng)前的request處理完才會處理下一個(gè)request,這種方式顯然很不合理,如果當(dāng)前的request處理過慢的話就會導(dǎo)致“堵塞”。正確的處理方式應(yīng)該是開辟新的進(jìn)程或線程去處理不同的request,通過混合繼承ForkingMixIn或ThreadingMixIn類即可解決此問題。

2、創(chuàng)建SocketServer

?????????使用SocketServer創(chuàng)建一個(gè)網(wǎng)絡(luò)服務(wù)程序只需要幾個(gè)簡單的步驟:

? ? ? ? ?(1)、創(chuàng)建處理request的類,創(chuàng)建方法為:繼承BaseRequestHandler類,并重載handle()方法。該方法將被回調(diào)用做處理當(dāng)前接收到的request。

? ? ? ? ?注意:一般的做法是直接繼承StreamRequestHandler或者DatagramRequestHandler。比如:

? ? ? ? ?class MyTCPHandler(SocketServer.StreamRequestHandler):

? ? ? ? ?(2)、實(shí)例化一個(gè)server基類(比如TCPServer)的對象,并發(fā)服務(wù)器地址和處理request的類作為參數(shù)傳入。

? ? ? ? ?(3)、使用server基類對象調(diào)用handle_request()或serve_forever()方法,即可處理一個(gè)或多個(gè)request。

? ? ? ? ?(4)、如果需要?jiǎng)?chuàng)建多進(jìn)程或多線程的服務(wù)器程序,則可以通過混合繼承ForkingMixIn或ThreadingMixIn類來實(shí)現(xiàn),比如:

? ? ? ? ?class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass //創(chuàng)建一個(gè)多線程的TCP服務(wù)器。

? ? ? ? ?注意:ThreadingMixIn必須要放在TCPServer前面。

3、server類方法說明:

(1)、class SocketServer.BaseServer

?????????這是所有類的超類,只定義接口,大部分均在子類中實(shí)現(xiàn)。

(2)、BaseServer.handle_request()

?????????該方法用于處理單一的request。按順序調(diào)用get_request(), verify_request()和???process_request().

(3)、BaseServer.serve_forever(poll_interval=0.5)

??????????????????循環(huán)輪詢處理request

(4)、BaseServer.address_family

?????????協(xié)議簇信息,比如socket.AF_INET and socket.AF_UNIX

(5)、BaseServer.RequestHandlerClass

?????????開發(fā)者自定義的用于處理request的類,每個(gè)request都會對應(yīng)實(shí)例化一個(gè)request handle???????類進(jìn)行處理。

(6)、BaseServer.server_address

?????????服務(wù)器要監(jiān)聽的地址和端口的二元組,比如(0.0.0.0,8080)

(7)、BaseServer.finish_request()

?????????實(shí)例化開發(fā)者自定義request handle類,然后調(diào)用handle()方法處理當(dāng)前的request。

(8)、

4、request handler類方法說明:

?????????由用戶自定義并傳入SocketServer,由server類實(shí)例化來處理當(dāng)前的request。需要注意的是:Request handler類必須要復(fù)寫handle()方法,其它方法也可以復(fù)寫,但不做強(qiáng)制。

(1)、RequestHandler.handle()

?????????開發(fā)者必須在此方法里面實(shí)現(xiàn)對當(dāng)前request的所有處理,在該方法里面有幾個(gè)實(shí)例化的屬性可以直接使用:self.request代表當(dāng)前的request對象,self.client_address代表客戶端地址,self.server代表服務(wù)器對象。對于TCP鏈接,self.request是當(dāng)前request的socket。self.rfile和self.wfile可分別用于讀取客戶端數(shù)據(jù)和向客戶端返回?cái)?shù)據(jù)。

5、樣例代碼:

5.1、創(chuàng)建TCP類型的SocketServer:

import SocketServer class MyTCPHandler(SocketServer.BaseRequestHandler): #定義request handler類,從BaseRequestHandler類繼承def handle(self): #復(fù)寫handle()方法,注意:該方法必須復(fù)寫,用于處理當(dāng)前的requestself.data = self.request.recv(1024).strip() #self.request是和客戶端連接的套接字,可直接使用print "{} wrote:".format(self.client_address[0])print self.dataself.request.sendall(self.data.upper())class MyTCPHandler(SocketServer.StreamRequestHandler): #定義request handler類,從StreamRequestHandler類繼承def handle(self):self.data = self.rfile.readline().strip() #self.rfile/self.wfile是文件格式類型的socket,相當(dāng)于對原始socket的封裝,讓讀寫網(wǎng)絡(luò)數(shù)據(jù)向讀寫文件一樣容易print "{} wrote:".format(self.client_address[0])print self.dataself.wfile.write(self.data.upper()) if __name__ == "__main__":HOST, PORT = "localhost", 9999server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler) #傳入監(jiān)聽地址、端口號和request handler類server.serve_forever() #啟動(dòng)監(jiān)聽處理request

?

5.2、創(chuàng)建UDP類型的SocketServer:

?

import SocketServerclass MyUDPHandler(SocketServer.BaseRequestHandler):def handle(self):data = self.request[0].strip()socket = self.request[1]print "{} wrote:".format(self.client_address[0])print datasocket.sendto(data.upper(), self.client_address) if __name__ == "__main__":HOST, PORT = "localhost", 9999server = SocketServer.UDPServer((HOST, PORT), MyUDPHandler) server.serve_forever()

?

?

?

5.3、創(chuàng)建多線程類型的TCP SocketServer:

import socket import threading import SocketServer class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):def handle(self):data = self.request.recv(1024)cur_thread = threading.current_thread()response = "{}: {}".format(cur_thread.name, data)self.request.sendall(response)class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):#繼承ThreadingMixIn表示使用多線程處理request,注意這兩個(gè)類的繼承順序不能變passdef client(ip, port, message):sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.connect((ip, port))try:sock.sendall(message)response = sock.recv(1024)print "Received: {}".format(response)finally:sock.close()if __name__ == "__main__":HOST, PORT = "localhost", 0server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)ip, port = server.server_addressserver_thread = threading.Thread(target=server.serve_forever)server_thread.daemon = Trueserver_thread.start()print "Server loop running in thread:", server_thread.nameclient(ip, port, "Hello World 1")client(ip, port, "Hello World 2")client(ip, port, "Hello World 3")server.shutdown()

?

轉(zhuǎn)載于:https://www.cnblogs.com/anningwang/p/9052633.html

總結(jié)

以上是生活随笔為你收集整理的使用Python SocketServer快速实现多线程网络服务器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。