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)
Dans le code modifié, le comportement a changé comme suit :
break
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 :
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> <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 :
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!