Heim  >  Artikel  >  Backend-Entwicklung  >  Erklären Sie, wie das SocketServer-Modul in Python Netzwerkanfragen verarbeitet

Erklären Sie, wie das SocketServer-Modul in Python Netzwerkanfragen verarbeitet

高洛峰
高洛峰Original
2017-03-01 14:17:581781Durchsuche

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Vorheriger Artikel:Kontextmanager in PythonNächster Artikel:Kontextmanager in Python