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

后端 未结 2 1802
星月不相逢
星月不相逢 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:14

    For receiving everything the server sends until it closes its side of the connection try this:

    import json
    import socket
    from functools import partial
    
    
    def main():
        message = 'Test'
    
        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
            sock.connect(('127.0.0.1', 9999))
    
            sock.sendall(message.encode('utf-8'))
            sock.shutdown(socket.SHUT_WR)
    
            json_response = b''.join(iter(partial(sock.recv, 4096), b''))
    
        response = json.loads(json_response.decode('utf-8'))
        print(response)
    
    
    if __name__ == '__main__':
        main()
    

    I've used sendall() because send() has the same ”problem” as recv(): It's not guaranteed everything is sent. send() returns the number of bytes actually sent, and the programmer has to make sure that matches the length of the argument and if not to send the rest until everything is out. After sending the writing side of the connection is closed (shutdown()) so the server knows there is no more data coming from the client. After that, all data from the server is received until the server closes its side of the connection, resulting in the empty bytes object returned from the recv() call.

    Here is a suitable socketserver.TCPServer for the client:

    import json
    from socketserver import StreamRequestHandler, TCPServer
    
    
    class Handler(StreamRequestHandler):
    
        def handle(self):
            print('Handle request...')
            message = self.rfile.read().decode('utf-8')
            print('Received message:', message)
            self.wfile.write(
                json.dumps(
                    {'name': 'John', 'age': 42, 'message': message}
                ).encode('utf-8')
            )
            print('Finished request.')
    
    
    
    def main():
        address = ('127.0.0.1', 9999)
        try:
            print('Start server at', address, '...')
            server = TCPServer(address, Handler)
            server.serve_forever()
        except KeyboardInterrupt:
            print('Stopping server...')
    
    
    if __name__ == '__main__':
        main()
    

    It reads the complete data from the client and puts it into a JSON encoded response with some other, fixed items. Instead of the low level socket operations it makes use of the more convenient file like objects the TCPServer offers for reading and writing from/to the connection. The connection is closed by the TCPServer after the handle() method finished.

提交回复
热议问题