code: private ResponseEncapsulation recvMessage() throws IOException {
      GeneratedMessage msg = null;
      byte[] headers = new byte[8];
      recv(headers, headers.length);
  
      if (headers[0] != 'L' || headers[1] != '1') {
        throw new IOException("Wrong launcher protocol header");
      }
  
      ByteBuffer buf = ByteBuffer.allocate(4);
      buf.order(ByteOrder.BIG_ENDIAN);
      buf.put(headers, 4, 4);
      buf.flip();
  
      int size = buf.getInt();
  
      logger.finest("RECV: type=" + ((int) headers[3]) + ", command="
                    + ((int) headers[2]) + ", size=" + size);
  
      byte[] data = new byte[size];
      recv(data, size);
  
      boolean success = (headers[3] == (byte) 1);
      MessageType type = MessageType.get(headers[2]);
  
      if (type == null) {
        throw new IOException("Unable to determine message type");
      }
  
      if ((headers[3] != (byte) 1) && (headers[3] != (byte) 2)) {
        throw new IOException("Unable to determine success or error");
      }
  
      switch (type) {
        case MSG_HELLO: {
          LauncherHandshakeResponse.Builder response = LauncherHandshakeResponse.newBuilder();
          buildMessage(response, data);
          msg = response.build();
          break;
        }
  
        case MSG_START:
        case MSG_STATUS:
        case MSG_STOP: {
          LauncherStatusResponse.Builder response = LauncherStatusResponse.newBuilder();
          buildMessage(response, data);
          msg = response.build();
          break;
        }
  
        case MSG_SCREENSHOT: {
          LauncherScreenshotResponse.Builder response = LauncherScreenshotResponse.newBuilder();
          buildMessage(response, data);
          msg = response.build();
          break;
        }
  
      }
  
      return new ResponseEncapsulation(success, msg);
    }
docs: Receive a message response.
  
  @return Response body and request status code
  @throws IOException if socket read error or protocol parse error