2

I'm trying to write my own WebSocket Server.

I know that there are some frameworks for this but i would like to learn, so I do it on my own :)

My JavaScript client reacts currently with onOpen, so I think the handshake is valid and the connection is established.

Now the problem:

My Java server uses a selector thread for reading on an Channel.

If I do *.send("test message") on the WebSocket object at my client, my server can't decode the byte array.

I found no information about the used encode/decode technology, so I tried many versions to decode.

for example:

new String(Base64.decodeBase64(buffer.array()))

or

Charset set = Charset.forName("UTF-8");
new String(Base64.decodeBase64(set.decode(buffer).toString()))

The message is completely read from the Channel into an ByteBuffer, so I don't think this is the problem.

Can anyone help me?


okay this Post helps me to send data to the Client. This works fine :)
But I don't understand how to decode the data received from the Client :(

At the Client i send only one Letter

socket.send("x");

The Server receives 7 byte ???

ByteBuffer buffer = ByteBuffer.allocate(8192);
int read = client.getInputStream().read(buffer2.array());
System.out.println("read: " + read);

// read: 7

for (int i = 0; i < read; i++) {
  int j = buffer.get(i) & 0xff;
  System.out.println("i: " + i + " => " + j + "=>" + new BigInteger(j + "").toString(2));
}

//i: 0 => 129=>10000001
//i: 1 => 129=>10000001
//i: 2 => 195=>11000011
//i: 3 => 235=>11101011
//i: 4 => 4=>100
//i: 5 => 96=>1100000
//i: 6 => 187=>10111011

If i do this

secondByte AND 0111 1111

the result of (i: 1) is "1" i think this means that there are only one byte data. Then why read is 7 ???

1

2 Answers 2

2

As for your second issue - the data from client to server is always masked as I also explained at the link above. Masks take 4 bytes.

So, the length of the actual data is indeed 1. Only the last 7 bits of the second byte say something about the length - the first bit doesn't, so just discard that one to get 000 0001 which is 1.

The bytes are categorised as follows in this case:

  • 0, 1 are meta bytes
  • 3, 4, 5, 6 are masks
  • 7 is the data

To get the data, calculate data XOR masks[data_index MOD 4], i.e. 187 XOR 195 in this case, which is 120 - the character code for x.

Sign up to request clarification or add additional context in comments.

Comments

2
private String decodeMessage(){
    try {
        byte[] data = new byte[1024];
        int size = in.read(data);
        if (size == -1) return null;
        byte[] decoded = new byte[size-6];
        byte[] key = new byte[]{ data[2], data[3], data[4], data[5] };
        for (int i = 0; i < size-6; i++) {
            decoded[i] = (byte) (data[i+6] ^ key[i & 0x3]);
        }
        return new String(decoded, "UTF-8");
    }catch (IOException ex){
        ex.printStackTrace();
    }
    return "ping";
}

This code is probably bad, but it works for me

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.