private void startReading() {
        if (!sock.isConnected() || sock.isClosed()) {
            disconnect();
            return;
        }
        buffer = new byte[buffer.length - bytesReceived];
        try {
            if (bytesReceived == -1) {
                disconnect();
                return;
            }

            bytesReceived += in.read(buffer);

            if (messageSize == -1) {
                if (bytesReceived == 4) {
                    messageSize = ByteBuffer.wrap(buffer).getInt(0);
                    
                    if (messageSize < 0) {
                        throw new Exception();
                    }

                    buffer = new byte[messageSize];
                    bytesReceived = 0;
                }

                if (messageSize != 0) {
                    startReading();
                }
            } else {
                if (bytesReceived == messageSize) {
                    StringBuffer sb = new StringBuffer();
                    sb.append(new String(buffer));
                    em.onMessageReceived(new MessageReceivedEvent(this, id, sb.toString()));

                    bytesReceived = 0;
                    messageSize = -1;
                    buffer = new byte[4];

                    startReading();
                } else {
                    startReading();
                }
            }
        } catch (Exception ignore) {
        }
    }