Heim >Backend-Entwicklung >Python-Tutorial >Wie ändert sich das TCP-Socket-Verhalten, wenn ein Server empfangene Daten nicht zurückmeldet?
TCP-Socket-Kommunikation: Socket-Verhalten verstehen
Bei der Arbeit mit TCP-Sockets in Python ist es wichtig, deren Stream-basierte Natur zu verstehen Verbindungen. Im Gegensatz zu Eins-zu-Eins-Beziehungen zwischen Sende- und Empfangsvorgängen wird der Datenfluss durch die implementierten Protokolle bestimmt.
Betrachten Sie den folgenden Codeausschnitt für einen einfachen Echo-Server:
import socket HOST = '' PORT = 50007 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(1) while True: data = s.recv(1024) if not data: break s.sendall(data)
In seiner ursprünglichen Form stellt dieser Code eine Verbindung mit einem Client her, wartet auf Daten vom Client und gibt diese zurück, bis der Client die Verbindung trennt. Die Schleife wird wiederholt durchlaufen, wobei der Server jede eingehende Nachricht empfängt und darauf antwortet.
Angenommen wir ändern jedoch den Code, um den Schritt auszuschließen, in dem der Server Daten an den Client zurücksendet:
import socket HOST = '' PORT = 50007 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(1) while True: data = s.recv(1024) if not data: break
In diesem Szenario ändert sich das Verhalten der recv-Methode. Wenn der geänderte Server eine Verbindung mit einem Client aufbaut, wartet er auf Daten. Da jedoch keine Daten gesendet werden, blockiert die Methode recv auf unbestimmte Zeit. Der zweite Aufruf von recv erfolgt nie, wodurch verhindert wird, dass der Server die Trennung des Clients erkennt.
Um dieses Verhalten zu verstehen, muss man sich unbedingt vor Augen halten, dass TCP-Sockets als Datenströme fungieren. Das Senden und Empfangen von Daten ist nicht direkt miteinander verknüpft. Die Regeln für die Kommunikation werden durch das implementierte Protokoll bestimmt. Im ursprünglichen Code schrieb das Protokoll vor, dass der Server alle vom Client empfangenen Daten zurückgeben würde.
Mit unserer Änderung ändert sich das Protokoll. Der Server empfängt nur noch Daten vom Client und verwirft diese. Der Client erwartet nach dem Senden der Daten eine Antwort, der geänderte Server bleibt jedoch stumm. Um dieses Problem zu beheben, muss der Client explizit angeben, dass er das Senden der Daten abgeschlossen hat, indem er seine ausgehende Verbindung schließt. Sobald dies geschieht, empfängt der Server einen leeren Recv-Aufruf, interpretiert ihn als Verbindungsabbruch und sendet die „OK“-Nachricht.
Darüber hinaus können in realen Szenarien Datenpakete während der Übertragung fragmentiert werden. Um dies zu berücksichtigen, würde eine robustere Client-Implementierung mehrere Recv-Aufrufe durchführen, bis alle Daten empfangen wurden.
Unten finden Sie aktualisierte Versionen des Server- und Client-Codes, die diese Probleme beheben:
Server:
import socket HOST = '' PORT = 50007 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((HOST, PORT)) s.listen(1) while True: data = s.recv(1024) if not data: break s.sendall(b'ok') s.shutdown(socket.SHUT_WR) s.close()
Client:
import socket HOST = 'localhost' PORT = 50007 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((HOST, PORT)) s.sendall(b'Hello, world') s.shutdown(socket.SHUT_WR) data = b'' while True: buf = s.recv(1024) if not buf: break data += buf s.close()
Von Durch die Umsetzung dieser Änderungen stellen wir sicher, dass die Kommunikation zwischen Server und Client wie vorgesehen funktioniert, indem wir Unterbrechungen erkennen und mit Datenfragmentierung umgehen.
Das obige ist der detaillierte Inhalt vonWie ändert sich das TCP-Socket-Verhalten, wenn ein Server empfangene Daten nicht zurückmeldet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!