Python socket.error: [Errno 111] Соединение отклонено

Я пытаюсь написать программу для передачи файлов с помощью сокетов. Конец сервера работает нормально. Однако на стороне клиента я получаю следующую ошибку:

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

Мой код выглядит следующим образом

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)

Я попытался найти помощь в Google и других сообщениях в Stack Overflow, ни одна из них не помогла. Может кто-нибудь, пожалуйста, помогите мне? Номера строк могут отличаться, поскольку я вставил только часть кода

Ответ 1

Очевидно, что проблема была (как вы поняли), что порт 36250 не был открыт на стороне сервера в то время, когда вы пытались подключиться (следовательно, соединение было отказано). Я вижу, что сервер должен был открыть этот сокет после получения команды SEND в другом соединении, но, по-видимому, он "не открывал [его] синхронно с клиентской стороной".

Ну, основная причина заключалась бы в отсутствии синхронизации. Призвание:

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

просто поместит данные в буфер ОС; close, вероятно, будет очищать данные и вставлять их в сеть, но почти наверняка будет возвращен до того, как данные достигнут сервера. Добавление sleep после close может уменьшить проблему, но это не синхронизация.

Правильным решением было бы убедиться, что сервер открыл соединение. Для этого потребуется, чтобы сервер отправил вам некоторое сообщение назад (например, OK или лучше PORT 36250, чтобы указать, где подключиться). Это позволит убедиться, что сервер уже прослушивает.

Другое дело: вы должны проверить возвращаемые значения SEND, чтобы убедиться, сколько байтов было взято из вашего буфера. Или используйте sendall.

(Извините за беспокойство по поводу этого позднего ответа, но я обнаружил, что это вопрос с высоким трафиком, и мне действительно не понравилась идея сна в разделе комментариев.)