Maison >développement back-end >Tutoriel Python >Pourquoi la suppression des données faisant écho à un serveur Python Socket entraîne-t-elle que « socket.recv() » ne renvoie rien lors des appels suivants ?

Pourquoi la suppression des données faisant écho à un serveur Python Socket entraîne-t-elle que « socket.recv() » ne renvoie rien lors des appels suivants ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-27 03:37:22982parcourir

Why Does Removing Data Echoing from a Python Socket Server Cause `socket.recv()` to Return Nothing on Subsequent Calls?

Socket Python : Comprendre l'impact du comportement de retour de données

Au départ, un exemple de serveur d'écho Python de la documentation officielle fonctionnait parfaitement. Cependant, lors de la modification du code pour éliminer l’envoi de données au client, un problème est survenu. La deuxième invocation de la méthode socket.recv() n'a donné aucun retour.

Implémentation différente, résultats différents

Le code original de la documentation utilisait une boucle while qui :

conn.sendall(data)

Cette ligne impliquait que le serveur renverrait les données reçues au client jusqu'à ce que le client ferme la fin de la connexion.

Dans le code modifié, le comportement a changé comme suit :

break

Lorsque la méthode conn.recv(1024) était appelée pour la deuxième fois, elle se terminerait immédiatement, ne laissant aucune donnée disponible pour l'utilisateur. client.

La nature des flux TCP

Pour comprendre ce comportement, il est essentiel de saisir la nature des flux TCP. Ils transmettent des données dans un flux continu, sans corrélation directe entre les opérations du client et du serveur. De plus, le protocole détermine les règles de communication sous-jacentes.

Dans le code original, le protocole dictait que le serveur ferait écho à chaque paquet de données qu'il recevait jusqu'à ce que le client ferme sa connexion sortante. À la fermeture, le serveur fermerait son socket.

Protocole modifié et ajustements du client

Le code modifié introduisait un nouveau protocole dans lequel le serveur rejetterait les données entrantes jusqu'à ce que le client fermé sa connexion sortante. Par la suite, le serveur envoyait "ok" et fermait son socket.

Pour faire fonctionner le client avec ce nouveau protocole, il fallait :

  1. Fermer la connexion sortante du client à indiquez l'achèvement.
  2. Implémentez plusieurs appels recv() pour tenir compte de la fragmentation potentielle des données transmission.

Serveur et client mis à jour

Les exemples de code mis à jour suivants illustrent la mise en œuvre révisée du protocole :

Serveur :

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('Connecté par', addr)</p>
<p>while Vrai :</p>
<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 :

importer prise

HOST = 'localhost'
PORT = 50007
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall (b'Bonjour, world')
s.shutdown(socket.SHUT_WR)
data = b''
while True :

data = conn.recv(1024)
if not data: break

s.close()
print('Received' , repr(data))

Avec ces implémentations révisées, le serveur élimine efficacement les données entrantes, permettant au client de recevoir sa réponse après la fermeture.

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