Skip to content

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

Description

@dlaoy

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

Activity

  1. self-assigned this
    on Jul 2, 2024
  2. PhilipRoman commented on Jul 2, 2024

    @PhilipRoman
    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

  3. dlaoy commented on Jul 2, 2024

    @dlaoy
    Author

    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

  4. dlaoy commented on Jul 2, 2024

    @dlaoy
    Author

    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'

  5. PhilipRoman commented on Jul 2, 2024

    @PhilipRoman
    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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions