how do we know the first 4 bytes read on a tcp socket are the length of the message?
Question: The ["Sending and receiving logging events across a
network"](https://docs.python.org/2/howto/logging-cookbook.html#sending-and-
receiving-logging-events-across-a-network) section of the python logging
cookbook demonstrates how a clients can send logs via a TCP session.

Log messages are pickled and sent to the server thanks to the [socket
handler](https://docs.python.org/2/library/logging.handlers.html#logging.handlers.SocketHandler).
The server then unpickle the messages and log them.

The code to get a message from the tcp socket is this one:

    
    
    class LogRecordStreamHandler(SocketServer.StreamRequestHandler):
        """Handler for a streaming logging request.
    
        This basically logs the record using whatever logging policy is
        configured locally.
        """
    
        def handle(self):
            """
            Handle multiple requests - each expected to be a 4-byte length,
            followed by the LogRecord in pickle format. Logs the record
            according to whatever policy is configured locally.
            """
            while True:
                chunk = self.connection.recv(4)
                if len(chunk) < 4:
                    break
                slen = struct.unpack('>L', chunk)[0]
                chunk = self.connection.recv(slen)
                while len(chunk) < slen:
                    chunk = chunk + self.connection.recv(slen - len(chunk))
                obj = self.unPickle(chunk)
                record = logging.makeLogRecord(obj)
                self.handleLogRecord(record)
    
        # then, methods to handle the record, but that's not the interesting part
    
    
    class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):
        """
        Simple TCP socket-based logging receiver suitable for testing.
        """
    
        allow_reuse_address = 1
    
        def __init__(self, host='localhost',
                     port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
                     handler=LogRecordStreamHandler):
            SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)
            self.abort = 0
            self.timeout = 1
            self.logname = None
    
        def serve_until_stopped(self):
            import select
            abort = 0
            while not abort:
                rd, wr, ex = select.select([self.socket.fileno()], [], [], self.timeout)
                if rd:
                    self.handle_request()
                abort = self.abort
    

What I don't understand in this example is: how do we know that the first 4
bytes we read from the socket constitute the length of the message? I looked
at the `socket`, and `logging` documentation but could not find mention of it.

Also, the docstring implicitly states that this code is not good enough for
production. What is so bad about that code?


Answer: As suggested in the comments, the answer is in the sending code (handlers.py
in python 2.7.10). I just removed the docstrings/comments that were obvious or
irrelevant to this question to make the code more readable.

    
    
    def makePickle(self, record):
        ei = record.exc_info
        if ei:
            dummy = self.format(record)
            record.exc_info = None
        d = dict(record.__dict__)
        d['msg'] = record.getMessage()
        d['args'] = None
        s = cPickle.dumps(d, 1)
        if ei:
            record.exc_info = ei
    
        # slen represents a "long integer", which is usually 32 bits large.
        slen = struct.pack(">L", len(s))
    
        # Here is where the 4 byte length is prepended to the message
        return slen + s
    
    
    def emit(self, record):
        try:
            s = self.makePickle(record)
            # s is actually (length of the message) + (message)
            self.send(s)
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)
    
    
    
    def send(self, s):
        """
        Send a pickled string to the socket.
    
        This function allows for partial sends which can happen when the
        network is busy.
        """
        if self.sock is None:
            self.createSocket()
    
        if self.sock:
            try:
                if hasattr(self.sock, "sendall"):
                    self.sock.sendall(s)
                else:
                    sentsofar = 0
                    left = len(s)
                    while left > 0:
                        sent = self.sock.send(s[sentsofar:])
                        sentsofar = sentsofar + sent
                        left = left - sent
            except socket.error:
                self.sock.close()
                self.sock = None  # so we can call createSocket next time
    

