public static Message ParseFromBytes(byte[] messageData)
    {
        //split header and body bytes bytes
        MessageHeader header       = MessageHeader.ParseFromBytes(messageData);
        int           headerLength = MessageHeader.HEADER_SIZE;

        byte[] headerBytes = new byte[headerLength];
        Array.Copy(messageData, 0, headerBytes, 0, headerLength);

        int bodySize = header.BodySize;

        byte[] bodyBytes = new byte[bodySize];
        Array.Copy(messageData, headerLength, bodyBytes, 0, bodySize);

        return(ParseFromBytes(headerBytes, bodyBytes));
    }
    public static Message ParseFromBytes(byte[] headerData, byte[] bodyData)
    {
        MessageHeader header = MessageHeader.ParseFromBytes(headerData);
        //Debug.Log("parseFromBytes. MessageType: " + header.getMessageType() + " compressed: " + header.isCompressed());
        MessageBody body = null;

        if (header.IsCompressed)
        {
            byte[] dataUncompressed = GZipUtils.Decompress(bodyData);
            body = new MessageBody(dataUncompressed);
        }
        else
        {
            body = new MessageBody(bodyData);
        }
        return(new Message(header, body));
    }
    void Listen()
    {
        IPAddress  ip            = IPAddress.Parse(host);
        IPEndPoint localEndPoint = new IPEndPoint(ip, Convert.ToInt32(port));

        listener = new Socket(ip.AddressFamily,
                              SocketType.Stream, ProtocolType.Tcp);
        listener.LingerState = new LingerOption(true, 0);

        try {// Bind the socket to the local endpoint and listen for incoming connections.
            Debug.Log("Binding socket to: " + localEndPoint);
            listener.Bind(localEndPoint);
            listener.Listen(10);

            while (!requestDisconnect)       //Start listening for connections.
            {
                handler = listener.Accept(); // Program suspended while waiting for an incoming connection.

                if (requestDisconnect)
                {
                    return;
                }

                //read header
                byte[]        headerBytes   = new byte[MessageHeader.HEADER_SIZE];
                int           bytesReceived = handler.Receive(headerBytes);
                MessageHeader header        = MessageHeader.ParseFromBytes(headerBytes);

                //if 0 bytes received, return. No valid message.
                if (bytesReceived == 0)
                {
                    if (requestDisconnect)
                    {
                        return;
                    }
                    continue;
                }

                Debug.Log("Got message type <" + header.MessageType + ">, Parsing: " + header.BodySize + "bytes");

                System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
                stopWatch.Start();

                //read body
                int    bodySize  = header.BodySize;
                byte[] bodyBytes = new byte[bodySize];

                int messageChunkSize = 100 * 1024;
                int messageBytesRead = 0;

                while (messageBytesRead < bodySize)
                {
                    if (requestDisconnect)
                    {
                        return;
                    }

                    byte [] bytes = new byte[messageChunkSize];

                    int bytesRec = handler.Receive(bytes);
                    if (bytesRec <= 0)
                    {
                        handler.Disconnect(true);
                        break;
                    }
                    Array.Copy(bytes, 0, bodyBytes, messageBytesRead, bytesRec);

                    messageBytesRead += bytesRec;

                    System.Threading.Thread.Sleep(1);
                }
                handler.Close();

                stopWatch.Stop();
                Debug.Log("Received " + messageBytesRead + " bytes in " + stopWatch.Elapsed.Milliseconds + " ms");
                stopWatch.Reset();

                //create message
                Message message = Message.ParseFromBytes(headerBytes, bodyBytes);

                ProtobufMessage protobufMessage = MessageDeserializer.DeserializeMessage(message);
                messageQueue.Enqueue(protobufMessage);

                System.Threading.Thread.Sleep(1);
            }
        } catch (Exception e) {
            Debug.Log("ERROR: " + localEndPoint + ": Exeception caught: " + e.ToString());
        }
    }