web-dev-qa-db-fra.com

Python socket.error: [Errno 111] Connexion refusée

J'essaie d'écrire un programme de transfert de fichiers à l'aide de sockets. L'extrémité serveur du code fonctionne correctement. Cependant, du côté client, j'obtiens l'erreur suivante

Traceback (most recent call last):
File "client.py", line 54, in <module>
uploadFiles(directory)
File "client.py", line 36, in uploadFiles
transferFile(fname)
File "client.py", line 13, in transferFile     
cs.connect((Host, 36258))
File "/usr/lib/python2.7/socket.py", line 224, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 111] Connection refused

Mon code est le suivant

import os
import socket

def transferFile(fname):
   Host = '127.0.0.1'
   CPORT = 36258
   MPORT = 36250
   FILE = fname
   cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   cs.connect((Host, 36258))
   cs.send("SEND " + FILE)
   cs.close()
   ms = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
   ms.connect((Host, MPORT))
   f = open(FILE, "rb")
   data = f.read()
   f.close()
   ms.send(data)
   ms.close()

def uploadFiles(directory):
   home = os.getenv("HOME")
   folder = str(home + "/" + directory)
   os.chdir(folder)
   dirList = os.listdir(folder)
   print dirList
   for fname in dirList:
       if fname.endswith('.bin'):
           transferFile(fname)

os.chdir(os.getenv("HOME"))
directory = "testdownload"
if not os.path.exists(directory):
   os.makedirs(directory)
 os.chdir(directory)

uploadFiles(directory)

J'ai essayé de chercher de l'aide sur Google et d'autres articles sur Stack Overflow, aucun d'eux n'a aidé. Quelqu'un peut-il m'aider? Les numéros de ligne peuvent être différents car je n'ai collé qu'une partie du code

20
hld619

Le problème était évidemment (comme vous l'avez compris) que le port 36250 n'était pas ouvert côté serveur au moment où vous avez essayé de vous connecter (d'où la connexion refusée). Je peux voir que le serveur était censé ouvrir ce socket après avoir reçu la commande SEND sur une autre connexion, mais apparemment il "ne l'ouvrait pas en synchronisation avec le côté client".

Eh bien, la principale raison serait qu'il n'y aurait aucune synchronisation. Appel:

cs.send("SEND " + FILE)
cs.close()

placerait simplement les données dans une mémoire tampon du système d'exploitation; close pourrait probablement vider les données et pousser dans le réseau, mais il reviendrait presque certainement avant que les données n'atteignent le serveur. L'ajout de sleep après close pourrait atténuer le problème, mais ce n'est pas de la synchronisation.

La bonne solution serait de assurez-vous le serveur a ouvert la connexion. Cela nécessiterait que le serveur vous renvoie un message (par exemple OK, ou mieux PORT 36250 pour indiquer où se connecter). Cela garantirait que le serveur écoute déjà.

L'autre chose est vous devez vérifier les valeurs de retour de send pour vous assurer du nombre d'octets pris dans votre tampon. Ou utilisez sendall .

(Désolé d'avoir dérangé avec cette réponse tardive, mais j'ai trouvé que c'était une question très fréquentée et je n'ai vraiment pas aimé l'idée de sommeil dans la section commentaires.)

18
tomasz