Maison >développement back-end >Tutoriel Python >Comment le comportement du socket TCP change-t-il lorsqu'un serveur ne renvoie pas les données reçues ?

Comment le comportement du socket TCP change-t-il lorsqu'un serveur ne renvoie pas les données reçues ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-03 03:36:13309parcourir

How Does TCP Socket Behavior Change When a Server Doesn't Echo Back Received Data?

Communication par socket TCP : comprendre le comportement des sockets

Lorsque vous travaillez avec des sockets TCP en Python, il est crucial de comprendre la nature basée sur le flux de ces sockets. relations. Contrairement aux relations un-à-un entre les opérations d'envoi et de réception, le flux de données est dicté par les protocoles mis en œuvre.

Considérez l'extrait de code suivant pour un simple serveur d'écho :

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)

Dans sa forme originale, ce code établit une connexion avec un client, attend les données du client et les renvoie jusqu'à ce que le client se déconnecte. La boucle itère à plusieurs reprises, le serveur recevant et répondant à chaque message entrant.

Cependant, supposons que nous modifiions le code pour exclure l'étape où le serveur renvoie les données au client :

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

Dans ce scénario, le comportement de la méthode recv change. Lorsque le serveur modifié établit une connexion avec un client, il attend des données. Cependant, comme aucune donnée n’est envoyée, la méthode recv se bloque indéfiniment. Le deuxième appel à recv n'a jamais lieu, empêchant le serveur de reconnaître la déconnexion du client.

Pour comprendre ce comportement, il est essentiel de rappeler que les sockets TCP fonctionnent comme des flux de données. L’envoi et la réception de données ne sont pas directement liés l’un à l’autre. Les règles régissant la communication sont déterminées par le protocole mis en œuvre. Dans le code d'origine, le protocole dictait que le serveur renvoyait toutes les données reçues du client.

Avec notre modification, le protocole change. Le serveur ne reçoit désormais que les données du client et les supprime. Le client attend une réponse après l'envoi des données, mais le serveur modifié reste silencieux. Pour résoudre ce problème, le client doit indiquer explicitement qu'il a terminé l'envoi des données en fermant sa connexion sortante. Une fois que cela se produit, le serveur reçoit un appel recv vide, l'interprète comme une déconnexion et envoie le message « OK ».

De plus, dans des scénarios réels, les paquets de données peuvent être fragmentés pendant la transmission. Pour tenir compte de cela, une implémentation client plus robuste effectuerait plusieurs appels recv jusqu'à ce que toutes les données soient reçues.

Vous trouverez ci-dessous des versions mises à jour du code serveur et client qui répondent à ces problèmes. problèmes :

Serveur :

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()

En mettant en œuvre ces changements, nous nous assurons que la communication entre le serveur et le client fonctionne comme prévu, reconnaissant les déconnexions et gérant la fragmentation des données.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn