Java socket error on linux (sent 0xFF, received -3)

While working on a WebSocket server in Java, I came across this strange error. I reduced it to two small java files, one of them is a server, the other is a client. The client simply sends 0x00 , the string Hello , and then 0xFF (according to the WebSocket specification).

On my Windows machine, the server prints the following:

 Listening byte: 0 72 101 108 108 111 recieved: 'Hello' 

In my unix block, the same code prints the following:

 Listening byte: 0 72 101 108 108 111 -3 

Instead of accepting 0xFF, it gets -3, never exits the loop, and never prints what it received.

The important part of the code looks like this:

 byte b = (byte)in.read(); System.out.println("byte: "+b); StringBuilder input = new StringBuilder(); b = (byte)in.read(); while((b & 0xFF) != 0xFF){ input.append((char)b); System.out.print(b+" "); b = (byte)in.read(); } inputLine = input.toString(); System.out.println("recieved: '" + inputLine+"'"); if(inputLine.equals("bye")){ break; } 

I also uploaded two files to my server:

My Windows computer is running Windows 7, and Debian is running on my Linux machine

Edit:
When b is int, it still acts weird. I send 0xFF (255), but I get 65533 (not 65535 or 255).

+4
source share
4 answers

The problem is not with the code you provided. Here:

 in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

You are dealing with binary data, so you should use a raw stream - do not turn it into a Reader , which is designed to read characters.

You get 65533 because the integer used for the Unicode replacement character is used when the value cannot be represented as a real Unicode character. The exact behavior of your current code will depend on the default encoding on your system, which again is not something you have to rely on.

Furthermore, you assume that each byte should translate to one character - essentially, you accept ISO-8859-1. I have not tested the specification, but I doubt that this is what you should use.

Finally, you do not verify that the value of b is -1, which is used to indicate that the client has closed the stream.

+11
source

Another solution for John above, just define the encoding as ISO-8859-1. By default, Java uses UTF-8.

 in = new BufferedReader(newInputStreamReader(kkSocket.getInputStream(),"ISO-8859-1")); 

Thus, Java correctly interprets bytes as the characters that you intended them.

This is necessary because 0xFF, which is your final byte, is an invalid char in UTF-8. Another option is to set the default encoding for Java for use in ISO-8859-1. http://en.wikipedia.org/wiki/UTF-8#Codepage_layout

I remember when Java changed from throwing an exception to replace char with a replacement character (int 65533).

+3
source

A byte with a value of -3 has a bit pattern of 11111101. And with a value of -3 has a bit pattern of 1111111111111111111111111111111101

So, you get almost the same value. I would like to understand why you get -3.

0
source

And your EOS check is incorrect. You should read in int and compare it with -1. If true, you have reached the end of the stream so close to the socket, or rather to the output stream, and act accordingly. Otherwise, add it in bytes. You cannot pass 0xff at the moment, because it will be handled in the same way as EOS.

0
source

Source: https://habr.com/ru/post/1309556/


All Articles