0

My goal is to decode message, sent by a client to the server through the WebSocket connection. The frame data have length, more on Base Framing Protocol [RFC6455].

I recently found out that read(byte[] b) outputs the entire frame.

For example, when a client send message abcdef to the server

byte[] frame = new byte[1000]
inputStream.read(frame); // [[-127, -122, -69, -122, 95, -5, -38, -28, 60, -97, -34, -32, 0, 0, ....]

However, the first byte should be 129 and the second byte should be 134. Is the only way to read the frame is through loop and use int[] instead of byte[] since the read() method outputs int instead of byte?

int[] frame = new frame[1000];
booean close = false;

frame[0] = inputStream.read();
frame[1] = inputStream.read();

int length = frame[1] & 127;

int pointer = 2;

while (!close) {
  frame[pointer] = inputStream.read();
  if (pointer == length) {
    close = true;
  }
}
Jason Rich Darmawan
  • 1,607
  • 3
  • 14
  • 31
  • 2
    Java bytes can't be 129 or 134. That's out of range. – Tom Jul 20 '21 at 03:34
  • @Tom I thought 8 bit range is between 0 - 255. Is the penalty performance of using int negligible? – Jason Rich Darmawan Jul 20 '21 at 03:48
  • That range is correct, for unsigned ranges. For singed ranges it is -128 - 127 and that's the range for byte here. Also see [Why is the range of bytes -128 to 127 in Java?](//stackoverflow.com/q/3621067) – Tom Jul 20 '21 at 03:53
  • The `read()` method returns `int` only because it needs to be able to return all valid byte values _and a sentinel value for EOF_. Using an `int` means the byte values are 0-255 and the sentinel value is -1. But the `read(byte[])` method returns the _number of_ bytes read, not the actual read bytes. The read bytes are placed in the `byte[]` array, which is an array of `byte`. In Java, all number primitives (except `char`?) are signed. That means the range of a `byte` is -128-127. But the values are still the "same" (e.g. -1 signed is 255 unsigned). – Slaw Jul 20 '21 at 05:30

1 Answers1

2

-127 'is' 129, i.e. it's 10000001, which is either number depending on whether it's signed or unsigned.

Read What is “2's Complement”? for more details on the format of signed binary numbers.

So you could use byte[] and convert bytes to int when you need to, e.g.

    public static void main(String... args) {
        byte b = -127;
        int i = b & 0xff;
        System.out.println("b = " + b + " i = " + i);
    }
tgdavies
  • 10,307
  • 4
  • 35
  • 40