Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSocket server fails to properly handle hexadecimal data from clients #1429

Open
dlaoy opened this issue Jul 2, 2024 · 4 comments
Open
Assignees

Comments

@dlaoy
Copy link

dlaoy commented Jul 2, 2024

Describe the bug
I have encountered an issue with my Android WebSocket server where it fails to correctly handle hexadecimal data sent from clients.

//java
//function
public byte[] hexStringToByteArray(String s) {
        int len = s.length();
        if (len % 2 != 0) {
            throw new IllegalArgumentException("Hex string must have an even length");
        }
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                    + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }

 @Override
    public void onMessage(WebSocket conn, ByteBuffer message) {
        //Log.d("websocket", "onMessage() Listen ByteBuffer data->"+ByteUtil.byteBufferToString(message));

        byte[] bytes = new byte[message.remaining()];
        message.get(bytes);

        Log.d("websocket", "onMessage() Listen ByteBuffer data->"+byteArrayToHexString(bytes));
        res.post(new Runnable() {
            @Override
            public void run() {
                res.setText("Byte Listen:"+byteArrayToHexString(bytes));
            }
        });
    }
//python socketClient
import asyncio
import websockets

async def send_byte_array():
    uri = "ws://192.168.0.102:9093"
    byte_data = bytes([0x02, 0x47, 0x00, 0xda, 0x5d, 0x4f, 0xf2, 0x02]) /// my byte

    async with websockets.connect(uri) as websocket:
        await websocket.send(byte_data)
        print("Sent byte data:", byte_data.hex())

async def receive_byte_array():
    uri = "ws://192.168.0.102:9093"  

    async with websockets.connect(uri) as websocket:
        while True:
            byte_data = await websocket.recv() 
            hex_string = byte_data.hex()
            print("Received byte data:", hex_string)

async def main():
    await asyncio.gather(send_byte_array(), receive_byte_array())

asyncio.get_event_loop().run_until_complete(main())

When running the Android WebSocket server and subsequently starting Python to send socket messages, the sent and received data do not match.

1719899969523

@PhilipRoman PhilipRoman self-assigned this Jul 2, 2024
@PhilipRoman
Copy link
Collaborator

I will check this when I get back home but I can tell you there is a 99% chance the issue is in your own code, not the library.

Please post your implementation of byteArrayToHexString also

@dlaoy
Copy link
Author

dlaoy commented Jul 2, 2024

byteArrayToHexString

    public static String byteArrayToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }

This is my byteArrayToHexString method

@dlaoy
Copy link
Author

dlaoy commented Jul 2, 2024

OK,I konw.This problem has been bothering me for a week.
The position in the ByteBuffer object is in position 4, causing it to be read starting from position 4.
For example:
bytes([0x02, 0x03, 0x06, 0x05]) -- position=0
bytes([0x02, 0x47, 0x00, 0xda, 0x5d, 0x4f, 0xf2, 0x02]) -- position=4
bytes([0x02, 0x47, 0x00, 0xda]) -- position=4
bytes([0x02, 0x47, 0x00, 0x06, 0x3f, 0x4d, 0xf9, 0x02]) -- position=7
bytes([0x02, 0x03, 0x00, 0x06, 0x02, 0x02, 0x02, 0x02]) -- position=0
bytes([0x02, 0xf9, 0x00, 0x06, 0x02, 0x02, 0x02]) -- position=2

My solution is:

@Override
    public void onMessage(WebSocket conn, ByteBuffer message) {
        //Log.d("websocket", "onMessage() Listen ByteBuffer data->"+ByteUtil.byteBufferToString(message));
        ByteBuffer messageCopy =message;
        messageCopy.position(0);                /// set the position on zero

        byte[] bytes = new byte[messageCopy.remaining()];
        messageCopy.get(bytes);
        sendToAllBytes(bytes);

        Log.d("websocket", "onMessage() Listen ByteBuffer data->"+ByteUtil.byteArrayToHexString(bytes));
        res.post(new Runnable() {
            @Override
            public void run() {
                res.setText("Byte Listen:"+ByteUtil.byteArrayToHexString(bytes));
            }
        });
    }

The version I am using is implementation group: 'org. java websocket', name: 'Java-WebSocket', version: '1.5.6'

@PhilipRoman
Copy link
Collaborator

Interesting, I would consider this a bug in the library. I noticed there are some inconsistencies with how ByteBuffer position/limit is handled by different functions, I guess we should go over API functions and add documentation or fix them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants