使用Python SocketServer快速实现多线程网络服务器
Python SocketServer使用介紹
1、簡介:
?????????SocketServer是python的一個網絡服務器框架,可以減少開發人員編寫網絡服務器程序的工作量。
? ? ? ? ?SocketServer總共有4個server基類。
? ? ? ? ?TCPServer:負責處理TCP協議。
? ? ? ? ?UDPServer:負責處理UDP協議。
? ? ? ? ?UnixStreamServer:只適用于類unix平臺,不常用。
? ? ? ? ?UnixDatagramServer:只適用于類unix平臺,不常用。
? ? ? ? ?這4個類會同步處理每一個request,也就是說只有當前的request處理完才會處理下一個request,這種方式顯然很不合理,如果當前的request處理過慢的話就會導致“堵塞”。正確的處理方式應該是開辟新的進程或線程去處理不同的request,通過混合繼承ForkingMixIn或ThreadingMixIn類即可解決此問題。
2、創建SocketServer
?????????使用SocketServer創建一個網絡服務程序只需要幾個簡單的步驟:
? ? ? ? ?(1)、創建處理request的類,創建方法為:繼承BaseRequestHandler類,并重載handle()方法。該方法將被回調用做處理當前接收到的request。
? ? ? ? ?注意:一般的做法是直接繼承StreamRequestHandler或者DatagramRequestHandler。比如:
? ? ? ? ?class MyTCPHandler(SocketServer.StreamRequestHandler):
? ? ? ? ?(2)、實例化一個server基類(比如TCPServer)的對象,并發服務器地址和處理request的類作為參數傳入。
? ? ? ? ?(3)、使用server基類對象調用handle_request()或serve_forever()方法,即可處理一個或多個request。
? ? ? ? ?(4)、如果需要創建多進程或多線程的服務器程序,則可以通過混合繼承ForkingMixIn或ThreadingMixIn類來實現,比如:
? ? ? ? ?class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass //創建一個多線程的TCP服務器。
? ? ? ? ?注意:ThreadingMixIn必須要放在TCPServer前面。
3、server類方法說明:
(1)、class SocketServer.BaseServer
?????????這是所有類的超類,只定義接口,大部分均在子類中實現。
(2)、BaseServer.handle_request()
?????????該方法用于處理單一的request。按順序調用get_request(), verify_request()和???process_request().
(3)、BaseServer.serve_forever(poll_interval=0.5)
??????????????????循環輪詢處理request
(4)、BaseServer.address_family
?????????協議簇信息,比如socket.AF_INET and socket.AF_UNIX
(5)、BaseServer.RequestHandlerClass
?????????開發者自定義的用于處理request的類,每個request都會對應實例化一個request handle???????類進行處理。
(6)、BaseServer.server_address
?????????服務器要監聽的地址和端口的二元組,比如(0.0.0.0,8080)
(7)、BaseServer.finish_request()
?????????實例化開發者自定義request handle類,然后調用handle()方法處理當前的request。
(8)、
4、request handler類方法說明:
?????????由用戶自定義并傳入SocketServer,由server類實例化來處理當前的request。需要注意的是:Request handler類必須要復寫handle()方法,其它方法也可以復寫,但不做強制。
(1)、RequestHandler.handle()
?????????開發者必須在此方法里面實現對當前request的所有處理,在該方法里面有幾個實例化的屬性可以直接使用:self.request代表當前的request對象,self.client_address代表客戶端地址,self.server代表服務器對象。對于TCP鏈接,self.request是當前request的socket。self.rfile和self.wfile可分別用于讀取客戶端數據和向客戶端返回數據。
5、樣例代碼:
5.1、創建TCP類型的SocketServer:
import SocketServer class MyTCPHandler(SocketServer.BaseRequestHandler): #定義request handler類,從BaseRequestHandler類繼承def handle(self): #復寫handle()方法,注意:該方法必須復寫,用于處理當前的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,相當于對原始socket的封裝,讓讀寫網絡數據向讀寫文件一樣容易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) #傳入監聽地址、端口號和request handler類server.serve_forever() #啟動監聽處理request?
5.2、創建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、創建多線程類型的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,注意這兩個類的繼承順序不能變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()?
轉載于:https://www.cnblogs.com/anningwang/p/9052633.html
總結
以上是生活随笔為你收集整理的使用Python SocketServer快速实现多线程网络服务器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CentOS是什么
- 下一篇: Python为什么这么厉害? 不想成为专