保持套接字监听 python,避免管道损坏错误

keep a socket listening python,avoid broken pipe error

我试图找到解决方案,但在任何 post 上都没有找到。 我正在尝试在两个套接字之间创建一个文件共享系统,但是当我的客户端连接到服务器时,在服务器第一次发送时,我收到了管道损坏错误。 我必须做些什么来保持套接字监听或任何其他方式我可以进行此传输? 我也是 运行 一个中央服务器,它使它的这两个客户端成为服务器-客户端对,与其中一个套接字在同一 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()

问题是在您的服务器程序中,您试图在错误的套接字上发送数据。

sock 是服务器(或主机,如果你愿意的话)套接字。这仅用于侦听传入连接。

[Python]: socket.accept() 文档状态:

Accept a connection. The socket must be bound to an address and listening for connections. The return value is a pair (conn, address) where conn is a new socket object usable to send and receive data on the connection, and address is the address bound to the socket on the other end of the connection.

  • 将您的线路(以及 所有 具有 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" 字符串,您将不会收到完整的内容。我建议让你的结束标签更复杂(所以它出现在文件中的机会尽可能少),或者更好:
    • 先发送文件大小,然后在客户端发送准确的字节数(可能需要检查