As @Rocky mentioned, it looks like you're mixing bits and bytes in your code.
This may help if you are thinking of a byte in binary format:
Binary Decimal Hex 00000000 0 0x00 00000001 1 0x01 00110000 48 0x30
If you look at the binary representation, you count the bits on the right: the byte has 8 bits, so bit 7 is the left-most bit, and bit 0 is the largest bit.
The reason why hexadecimal (base-16) notation is so convenient is because it is easier to convert between binary and hexadecimal than binary to hex.
Take the binary number 00110000. If you divide them into two parts (0011) and (0000), which are called the high jib (bit 7-4) and the low nibble (bit 3-0). Then you can easily convert two nibbles to hex:
Nibble Hex Decimal 0000 0 0 0001 1 1 0010 2 2 0011 3 3 0100 4 4 0101 5 5 0110 6 6 0111 7 7 1000 8 8 1001 9 9 1010 A 10 1011 B 11 1100 C 12 1101 D 13 1110 E 14 1111 F 15
Combining the two pieces, you can see the relationship between hexadecimal and binary:
Binary 0011 1100 Hex 3 C so binary 00110100 = hex 34 = dec 60
So, back to your binary format:
In the request packet you get a response (hex 30), so if you convert it to your bit:
Hex 30 = binary 0011 0000
You can see that bits 5 and 4 are set.
To dynamically set bits in a byte, you need to use the logical logic AND and OR. For results and / or on one bit, see the following:
Bit Bit Result Result Result AB AND OR XOR 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0
You also have a NOT operation
Bit Result NOT 0 1 1 0
With multiple bits, you simply perform an operation on each bit (bit 7 to 0), for example:
01101010 (hex 6A) AND 11100110 (hex E6) = 01100010 (hex 62) 01101010 (hex 6A) OR 11100110 (hex E6) = 11101110 (hex EE) NOT 00111001 (hex 3B) = 11000110 (hex C6)
Thus, bearing in mind, you can use the following operations to set and clear individual bits in a byte:
If you want to make sure bit 6 is set (1), you just need OR with 01000000 (hex 40)
xxxxxxxx (any value) OR 01000000 (hex 40) = x1xxxxxx
If you want to make sure bit 6 is clear (0), you just need AND with NOT (hex 40), so
NOT 01000000 (hex 40) = 10111111 (hex BF) xxxxxxxx (any value) AND 10111111 (hex BF) = x0xxxxxx
To put all this into Java code, you have the following binary operators:
- | binary OR
- & binary And
- ~ binary NOT
So, if you want to set a bit in a byte:
byte anyByte; anyByte = anyByte | 0x40;
which can be reduced to
anyByte |= 0x40;
If you want to clear the bit:
anyByte &= ~0x40;
If you want to check if the bit is set, you should use the following:
if ((anyByte & 0x40) == 0x40) ...
If you want to check whether bit 4 and bit 1 have been set, you must do the following:
if ((anyByte & 0x12) == 0x12) ...
Why is 0x12? Because hex 12 is binary 0001 0010 , which βmasksβ bits 4 and 1.
Back to your question:
To send the correct command line, you just need to create the correct byte array, as indicated in the manual, although I hope it is now clearer to set the bits in bytes:
Socket s = new Socket("192.168.1.2", 49137); InputStream in = s.getInputStream()); // send the request // (Note, for different requests, you'll need different, byte arrays and may // even have different lengths (can't tell without having seen the whole manual) byte[] st = new byte[] { 0x01, 0x30, 0x01, 0x00 }; OutputStream out = s.getOutputStream(); out.write(st); out.flush(); // read the first header byte (bits indicate the rest of the header structure) byte header = (byte)in.read(); // bit 1 shows whether the header represented in 2 bytes boolean header2Byte = (header & 0x2) != 0; // bit 2 shows whether the length is represented in 2 bytes boolean len2Byte = (header & 0x4) != 0; if (header2Byte) { // need to read the extra header (discarded here) in.read(); } // missed off reading the command byte/s int len = 0; if (len2Byte) { byte[] lenByte = new byte[2]; in.read(lenByte); if (isLittleEndian) { len = (lenByte[1] << 8) + lenByte[0]; } else { len = (lenByte[0] << 8) + lenByte[1]; } } else { // only one byte signifies the length len = is.read(); } byte[] data = new byte[len]; in.read(data); // it is unclear what format the data, has but if it is a string, and encoded as // UTF-8, then you can use the following String stringData = new String(data, "UTF-8"); System.out.println(stringData); // note, try-catch-finally omitted for brevity in.close(); out.close(); s.close();
Please note: I do not use DataInputStream here, as the way Java encodes integers may differ from how the device encodes its integers. For instance. in Java and integer - 4 bytes and Big Endian (see also this SO article ).
The NB operator << is a left shift operator that shifts bits along a byte, and the above case is used to combine two byte into a 16-bit number. A left shift of 8 is equivalent to multiplying by 256.