сохранить сокет прослушивания Python, избежать ошибки сломанной трубы - PullRequest
0 голосов
/ 14 мая 2018

Я пытался найти решение, но не нашел ни одного сообщения. Я пытаюсь создать систему обмена файлами между двумя сокетами, но когда мой клиент подключается к серверу, при первой отправке сервером я получаю сообщение об ошибке сломанного канала. Есть ли что-то, что я должен сделать, чтобы прослушивание сокета или каким-либо другим способом я могу сделать эту передачу? Я также использую центральный сервер, который делает этих двух своих клиентов парой сервер-клиент на том же ip, что и на одном из сокетов. может ли это вызвать эту проблему (я ставлю его на сон после создания временной пары) вот код сервера:

 def create_server(self,ip,path ): #ip is of the server
    connection_list = []
    print(ip)
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((ip, 12345))
    print("server created")
    connection_list.append(sock)
    sock.listen(1)
    #offset = 0
    file = open(path, "rb")
    print("file opened")
    while True:
        print("waiting for connection...")
        conn, addr = sock.accept()
        print ('New connection from %s:%d' % (addr[0], addr[1]))
        print("accepted connection")
        connection_list.append(conn)           
        sock.send(str("Start").encode()) # THIS CAUSES BROKEN PIPE ERROR
        chunk = file.read(4096)
        print("chunk read")
        if not chunk:
            break  # EOF
        sock.send(chunk)
        print("chunk sent")
    sock.send(str("ENDED").encode())
    print("Transfer complete")
    sock.close()

это код клиента:

def create_client(self,ip,file ): #ip of server
    print(ip)
    print("going to download",str(file))
    try:
        client=socket.create_connection((ip, 12345 ))
    except:
        client=socket.create_connection((ip, 12346 ))
    print("client created")
    with open(str(file), 'wb') as f:
      socket_list = [client]
      print("file opened")
      data=client.recv(4096)
      while data.decode()!="Start":
                        data=client.recv(4096)
      while True:
           print("started")
           data=client.recv(4096)
           print("recieved data")
           if data.decode()=="ENDED":
                   break
      f.write(data)
      print("Transfer complete")
    f.close()
    time.sleep(5)
    client.close()

1 Ответ

0 голосов
/ 14 мая 2018

Проблема в том, что в вашей серверной программе вы пытаетесь отправить данные не в тот сокет.

sock - сокет сервера (или главного, если хотите). Используется только для прослушивания входящих соединений.

[Python]: сокет. принять () состояния документации:

Принять соединение. Сокет должен быть привязан к адресу и прослушивать соединения. Возвращаемое значение представляет собой пару (conn, address), где conn - это новый объект сокета, используемый для отправки и получения данных по соединению и address - это адрес, связанный с сокетом на другом конце соединения.

  • Измените свою строку (и все другие строки, имеющие sock.send) с:

    sock.send(str("Start").encode())
    

    до:

    conn.send("Start".encode())
    
  • Строки:

    conn.send("ENDED".encode())
    print("Transfer complete")
    

    следует перемещать внутри цикла while (с отступом), и, возможно, вы могли бы добавить conn.close() в конце цикла.

В вашей клиентской программе:

  • Предложение try / except бесполезно, поскольку сервер не прослушивает порт 12346
  • Если файл содержит строку "ENDED" , вы не получите полное содержимое. Я бы посоветовал сделать ваш конечный тег более сложным (чтобы было как можно меньше шансов присутствовать в файле) или лучше
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...