SajanGohil
SajanGohil

Reputation: 969

keep a socket listening python,avoid broken pipe error

I tried to find the solution but did not find any on any post. I am trying to create a file sharing system between two sockets but as my client connects to server, on first send by server I get broken pipe error. Is there something I have to do to keep the socket listening or any other way I can do this transfer? I am also running a central server that makes these two of its clients a server-client pair on the same ip as one of the socket. could that cause this problem(i put it on sleep after it creates the temporary pair) here is the server code:

 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()

this is the client code:

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()

Upvotes: 0

Views: 1721

Answers (1)

CristiFati
CristiFati

Reputation: 41137

The problem is that in your server program, you're trying to send data on the wrong socket.

sock is the server (or the master, if you will) socket. That is only used to listen for incoming connections.

[Python]: socket.accept() documentation states:

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.

  • Change your line (and all the other lines that have sock.send) from:

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

    to:

    conn.send("Start".encode())
    
  • The lines:

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

    should be moved inside the while loop (indented), and perhaps you could add a conn.close() at the end of the loop.

In your client program:

  • The try / except clause is useless, since the server doesn't listen on port 12346
  • If the file contains an "ENDED" string, you won't receive the complete content. I'd suggest to make your end tag more complex (so there are as least chances as possible for it to be present in the file), or better:

Upvotes: 1

Related Questions