SocketServer erstellt ein Netzwerkdienst-Framework. Es definiert Klassen zur Verarbeitung synchroner Netzwerkanforderungen über TCP, UDP, UNIX-Streams und UNIX-Datagramme.
1. Servertypen
Es gibt fünf verschiedene Serverklassen in SocketServer.
1.BaseServer definiert die API und wird nicht zur Instanziierung und direkten Verwendung verwendet.
2.TCPServer wird für die TCP/IP-Socket-Kommunikation verwendet.
3.UDPServer verwendet Datagramm-Sockets.
4.UnixStreamServer und UnixDatagramServer verwenden Unix-Domänen-Sockets und werden intelligent auf Unix-Plattformen eingesetzt.
2. Serverobjekte
Erstellen Sie einen Server, über den die angeforderte Adresse und Anforderungsverarbeitungsklasse (nicht Instanz) überwacht werden kann.
1.Klasse SocketServer.BaseServer
Dies ist die Superklasse aller Serverobjekte im Modul. Sie definiert die Schnittstelle und der größte Teil der Implementierung wird in Unterklassen abgeschlossen.
2.BaseServer.fileno
Gibt einen ganzzahligen Dateideskriptor zurück, um anzugeben, welcher Server lauscht. Diese Funktion wird am häufigsten an select.select() übergeben, sodass mehrere Dienste denselben Prozess überwachen können.
3.BaseServer.handle_request
Um eine einzelne Anfrage zu verarbeiten, ruft diese Funktion nacheinander die folgenden Methoden auf. get_request(), verify_request und proccess_request.
Der Benutzer stellt die Methode handle() bereit und löst eine Ausnahme aus. Anschließend wird die Methode handle_error() aufgerufen.
Wenn innerhalb von self.timeout keine Anfrage empfangen wird, kehren handle_timeout() und handle_request() zurück.
4.BaseServer.serve_forever
BaseServer.serve_forever(poll_interval=0.5), verarbeitet die Anfrage bis zur expliziten Shutdown()-Anfrage. Das Rotationstraining wird jedes Mal poll_interval geschlossen. Ignorieren Sie self.timeout. Wenn Sie geplante Aufgaben verwenden müssen, müssen Sie andere Threads verwenden.
5.BaseServer.shutdown
weist servo_forever() an, die Schleife zu stoppen.
6.BaseServer.RequestHandlerClass
Benutzeranforderungshandlerklasse, erstellen Sie für jede Anforderung eine Instanz dieser Klasse.
3. Implementieren eines Servers
Wenn Sie einen Server erstellen, kann dieser normalerweise vorhandene Klassen wiederverwenden und einfach eine benutzerdefinierte Anforderungsverarbeitungsklasse bereitstellen. Es gibt mehrere BaseServer-Methoden zum Überschreiben einer Unterklasse, wenn diese Ihren Anforderungen nicht entspricht.
1.verify_request(reqeust, client_address): Muss einen booleschen Wert zurückgeben. Wenn True zurückgegeben wird, wird die Anfrage verarbeitet. Wenn False zurückgegeben wird, wird die Anfrage abgelehnt. Diese Funktion kann überschrieben werden, um Zugriffskontrolldienste zu implementieren.
2.process_request(request, client_address): Rufen Sie finish_request auf, um eine Instanz von RequestHandlerClass() zu erstellen. Bei Bedarf kann diese Funktion einen neuen Prozess oder eine neue Coroutine zur Bearbeitung der Anfrage erstellen.
3.finish_request(request, client_address): Erstellen Sie eine Anfrageverarbeitungsinstanz. Rufen Sie handle() auf, um die Anfrage zu bearbeiten.
4. Request-Handler
Request-Handler erledigen den größten Teil der Arbeit, um eingehende Anfragen zu empfangen und zu entscheiden, welche Maßnahmen ergriffen werden sollen. Der Handler ist für die Implementierung der Socket-Schicht auf dem „Protokoll“ (z. B. HTTP oder XML-RPC) verantwortlich. Liest die Anfragedaten vom eingehenden Anfragehandler, verarbeitet sie und schreibt eine Antwort. Es gibt drei Möglichkeiten, dies zu überschreiben.
1.setup(): Bereiten Sie den Anforderungshandler für die Anforderung vor, der vor dem Handle initialisiert und ausgeführt wird.
2.handle(): Erledigt die eigentliche Anforderungsarbeit. Analysieren Sie eingehende Anfragen, verarbeiten Sie Daten und geben Sie Antworten zurück.
3.finish(): Bereinigen Sie jederzeit das erstellte setup().
5. Beispiele
Das folgende Beispiel zeigt TCP, UDP und asynchrones
1.TCPServer-Beispiel
import SocketServer class MyHandler(SocketServer.BaseRequestHandler): def handle(self): self.data = self.request.recv(1024).strip() print '{} wrote:'.format(self.client_address[0]) print self.data self.request.sendall(self.data.upper()) if __name__ == '__main__': HOST, PORT = 'localhost', 9999 server = SocketServer.TCPServer((HOST, PORT), MyHandler) server.serve_forever()
2. UDPServr-Beispiel
import SocketServer class MyHandler(SocketServer.BaseRequestHandler): def handle(self): data = self.request[0].strip() socket = self.request[1] print '{} wrote:'.format(self.client_address[0]) print data socket.sendto(data.upper(), self.client_address) if __name__ == '__main__': HOST, PORT = 'localhost', 9999 server = SocketServer.UDPServer((HOST, PORT), MyHandler) server.serve_forever()
3. Asynchrone Beispiele
Asynchrone Handler können über die Klassen ThreadingMixIn und ForkingMixIn erstellt werden.
import socket import threading import SocketServer class MyHandler(SocketServer.BaseRequestHandler): def handle(self): data = self.request.recv(1024) curr_thread = threading.current_thread() response = '{}: {}'.format(curr_thread.name, data) self.request.sendall(response) class Server(SocketServer.ThreadingMixIn, SocketServer.TCPServer): pass def 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', 0 server = Server((HOST, PORT), MyHandler) ip, port = server.server_address serer_thread = threading.Thread(target=server.serve_forever) server_thread.daemon = True server_thread.start() print 'Server loop running in thread:', server_thread.name client(ip, port, 'Hello World 1') client(ip, port, 'Hello World 2') client(ip, port, 'Hello World 3') server.shutdown() server.server_close()
4.SocketServer realisiert nicht blockierende Kommunikation zwischen Client und Server
(1 ) SocketServerTCP-Server erstellen
#创建SocketServerTCP服务器: import SocketServer from SocketServer import StreamRequestHandler as SRH from time import ctime host = 'xxx.xxx.xxx.xxx' port = 9999 addr = (host,port) class Servers(SRH): def handle(self): print 'got connection from ',self.client_address self.wfile.write('connection %s:%s at %s succeed!' % (host,port,ctime())) while True: data = self.request.recv(1024) if not data: break print data print "RECV from ", self.client_address[0] self.request.send(data) print 'server is running....' server = SocketServer.ThreadingTCPServer(addr,Servers) server.serve_forever()
(2) SocketServerTCP-Client erstellen
from socket import * host = 'xxx.xxx.xxx.xxx' port = 9999 bufsize = 1024 addr = (host,port) client = socket(AF_INET,SOCK_STREAM) client.connect(addr) while True: data = raw_input() if not data or data=='exit': break client.send('%s\r\n' % data) data = client.recv(bufsize) if not data: break print data.strip() client.close()
Weitere Erklärungen, wie das SocketServer-Modul in Python Netzwerkanfragen verarbeitet, finden Sie auf der chinesischen PHP-Website für verwandte Artikel!