Warum bleibt „socket.recv()' stehen, wenn der Server keine Daten zurücksendet?

Patricia Arquette
Freigeben: 2024-11-22 22:33:26
Original
846 Leute haben es durchsucht

Why Does `socket.recv()` Stall When the Server Doesn't Send Data Back?

Socket-Verhalten verstehen: Warum Socket.recv() ohne gesendete Daten blockiert

Python-Sockets verhalten sich wie TCP-Verbindungen wie Datenströme die zwischen Clients und Servern fließen. In diesem Artikel werden die Gründe für das Problem erläutert, bei dem ein socket.recv()-Aufruf keine Daten zurückgibt, nachdem die Datenübertragung geändert wurde.

Das Echo-Server-Beispiel

Betrachten Sie das Python-Echoserver-Beispiel aus der offiziellen Dokumentation. Dieser Server lauscht auf eingehende Verbindungen, empfängt Daten und sendet sie an den Client zurück. Der folgende Codeausschnitt reproduziert das ursprüngliche Serververhalten:

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
    conn.sendall(data)
conn.close()
Nach dem Login kopieren

Änderung des Serververhaltens

Das Problem tritt auf, wenn der Code so geändert wird, dass keine Daten an den Client zurückgesendet werden :

while True:
    data = conn.recv(1024)
    if not data: break
conn.close()
Nach dem Login kopieren

In diesem modifizierten Code empfängt die while-Schleife endlos Daten vom Client, aber der Server sendet niemals Daten zurück. Dies führt dazu, dass der Client beim Aufruf von socket.recv() auf unbestimmte Zeit blockiert.

Den Kommunikationsfluss verstehen

TCP-Sockets pflegen keine Eins-zu-eins-Beziehung zwischen dem Senden und Empfangen von Anrufen an verschiedenen Endpunkten. Stattdessen definiert das Protokoll die Regeln für die Kommunikation. In diesem Fall hat der ursprüngliche Echo-Server eine Regel implementiert, nach der der Server die empfangenen Daten zurückgibt, bis der Client die Verbindung schließt.

Wenn das Serververhalten geändert wird, wurden die Regeln effektiv geändert. Der Server empfängt nun nur noch Daten und verwirft diese, bis der Client die Verbindung schließt. Der Server sendet niemals Daten zurück an den Client.

Anpassen des Client-Verhaltens

Um mit dem geänderten Server arbeiten zu können, muss der Client sein Verhalten anpassen. Da der Server keine Daten mehr aktiv sendet, geht der Client davon aus, dass der Empfang von Daten auf eine abgeschlossene Verbindung hinweist. Um dies zu erleichtern, sollte der Client seine ausgehende Seite der Verbindung schließen, um dem Server zu signalisieren, dass er mit dem Senden der Daten fertig ist. Der Client kann dann mehrere recv-Aufrufe ausführen, um eine mögliche Fragmentierung der eingehenden Daten zu bewältigen.

Aktualisierter Code

Unten finden Sie aktualisierten Code sowohl für den Server als auch für den Client hält sich an die geänderten Regeln von Kommunikation:

Server:

import socket

HOST = ''
PORT = 50007 
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((HOST, PORT))
s.listen(1)

conn, addr = s.accept()
print('Connected by', addr)

while True:
    data = conn.recv(1024)
    if not data: break
conn.sendall(b'ok')
conn.shutdown(socket.SHUT_WR)
conn.close()
Nach dem Login kopieren

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()
print('Received', repr(data))
Nach dem Login kopieren

Durch das Verständnis der Stream-basierten Natur von TCP-Sockets und die entsprechende Anpassung der Kommunikationsregeln können das Problem beheben, bei dem socket.recv() ins Stocken gerät, ohne dass Daten gesendet werden.

Das obige ist der detaillierte Inhalt vonWarum bleibt „socket.recv()' stehen, wenn der Server keine Daten zurücksendet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
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
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage