Python Socket: Die Auswirkungen des Datenrückgabeverhaltens verstehen
Anfangs funktionierte ein Python-Echoserver-Beispiel aus der offiziellen Dokumentation einwandfrei. Bei der Änderung des Codes, um das Zurücksenden von Daten an den Client zu verhindern, trat jedoch ein Problem auf. Der zweite Aufruf der Methode socket.recv() ergab keine Rückgabe.
Unterschiedliche Implementierung, unterschiedliche Ergebnisse
Der ursprüngliche Code aus der Dokumentation verwendete eine While-Schleife, die:
conn.sendall(data)
Im geänderten Code änderte sich das Verhalten wie folgt:
break
Die Natur von TCP-Streams
Um dieses Verhalten zu verstehen, ist es wichtig, die Natur von TCP-Streams zu verstehen. Sie übertragen Daten in einem kontinuierlichen Fluss, ohne direkte Korrelation zwischen Client- und Servervorgängen. Darüber hinaus bestimmt das Protokoll die zugrunde liegenden Kommunikationsregeln.
Im Originalcode schrieb das Protokoll vor, dass der Server jedes empfangene Datenpaket so lange wiederholt, bis der Client seine ausgehende Verbindung schließt. Beim Schließen würde der Server seinen Socket schließen.
Geänderte Protokoll- und Client-Anpassungen
Der geänderte Code führte ein neues Protokoll ein, bei dem der Server eingehende Daten bis zum Client verwirft hat seine ausgehende Verbindung geschlossen. Anschließend sendete der Server „ok“ und schloss seinen Socket.
Damit der Client mit diesem neuen Protokoll funktioniert, war Folgendes erforderlich:
Aktualisierter Server und Client
Die folgenden aktualisierten Codebeispiele veranschaulichen die überarbeitete Protokollimplementierung:
Server:
import socket</p> <p>HOST = ''<br>PORT = 50007 <br>s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br>s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)<br>s.bind((HOST, PORT))<br> s.listen(1)</p> <p>conn, addr = s.accept()<br>print('Connected by', addr)</p> <p>while True:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">data = conn.recv(1024) if not data: break
conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()
Client:
import socket</p> <p>HOST = 'localhost'<br>PORT = 50007<br>s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)<br>s.connect((HOST, PORT))<br>s.sendall (b'Hallo, world')<br>s.shutdown(socket.SHUT_WR)<br>data = b''<br>while True:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">data = conn.recv(1024) if not data: break
s.close()
print('Received' , repr(data))
Mit diesen überarbeiteten Implementierungen ist der Server Verwirft eingehende Daten effizient, sodass der Client seine Antwort nach dem Schließen erhalten kann.
Das obige ist der detaillierte Inhalt vonWarum führt das Entfernen von Datenechos von einem Python-Socket-Server dazu, dass „socket.recv()' bei nachfolgenden Aufrufen nichts zurückgibt?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!