Pickle EOFError: Ran out of input when recv from a socket

后端 未结 2 1830
星月不相逢
星月不相逢 2021-01-17 02:09

I am running a very simple python (3.x) client-server program (both locally on my PC) for a school project (not intended for the real world) which just sends messages back-a

2条回答
  •  半阙折子戏
    2021-01-17 02:34

    The problem with your code is that recv(4096), when used on a TCP socket, might return different amount of data from what you might have expected, as they are sliced at packet boundaries.

    The easy solution is to prefix each message with length; for sending like

    import struct
    packet = pickle.dumps(foo)
    length = struct.pack('!I', len(packet)
    packet = length + packet
    

    then for receiving

    import struct
    
    buf = b''
    while len(buf) < 4:
        buf += socket.recv(4 - len(buf))
    
    length = struct.unpack('!I', buf)[0]
    # now recv until at least length bytes are received,
    # then slice length first bytes and decode.
    

    However, Python standard library already has a support for message oriented pickling socket, namely multiprocessing.Connection, that supports sending and receiving pickles with ease using the Connection.send and Connection.recv respectively.

    Thus you can code your server as

    from multiprocessing.connection import Listener
    
    PORT = 1234
    server_sock = Listener(('localhost', PORT))
    conn = server_sock.accept()
    
    unpickled_data = conn.recv()
    

    and client as

    from multiprocessing.connection import Client
    
    client = Client(('localhost', 1234))
    client.send(['hello', 'world'])
    

提交回复
热议问题