Search code examples
pythonsocketsserverclientclient-server

infinite loop when receiving a large pickled object with sockets


I'm using a remote linux server and I want to send an array via sockets from client with python so I used this code :

message = pickle.dumps(faceBlob)
message_header = bytes(f"{len(message):<{HEADER_LENGTH}}", "utf-8")
client_socket.send(message_header + message)

to receive it in the server I used a while loop to catch all the message since it is > 4096 :

def receive_blop(client_socket):
    # Receive our "header" containing message length, it's size is defined and constant
    message_header = client_socket.recv(HEADER_LENGTH)

    # If we received no data, client gracefully closed a connection, for example using socket.close() or socket.shutdown(socket.SHUT_RDWR)
    if not len(message_header):
        return False

    # Convert header to int value
    message_length = int(message_header.decode('utf-8').strip())
    fragments = []
    print(message_length)

    while True:
        # this loop is infinite

        print("I arrived her")
        chunk = client_socket.recv(4096)
        if not chunk:
            break
        fragments.append(chunk)

    data_arr = b"".join(fragments)


    # Return an object of message header and message data
    return {'header': message_header, 'data': data_arr}

the server still printing the 'I arrived here' but receive the message until the connection is ended from the client


Solution

  • Your loop will continue until the client closes the connection. If they don't close until they get a response from you, you've got a deadlock.

    Since you know the message length, you can stop the loop when you've received that many bytes.

        received_length = 0
        while received_len < message_length:
    
            print("I arrived her")
            chunk = client_socket.recv(message_length - received_length)
            if not chunk:
                break
            fragments.append(chunk)
            received_length += len(chunk)