Reputation: 21
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 ???
Upvotes: 2
Views: 4640
Reputation: 121
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
Upvotes: 2
Reputation: 154818
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:
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
.
Upvotes: 2