How to send such complex data in hex format, binary protocol using java-bytes []?

I am very confused about such things. What should I send as the final command, always confuse 8 bits to 1 byte, but how to do it? Is this just a [hex] command package, as shown in the screenshot? or Is this the header + command [hex] shown in two screenshots?

Confusion Details:

  • In such a block of the chart header, mainly β€œbit 7, bit 6, .., bit 0” is displayed instead of β€œbit 0, bit 1, bit 2, ... bit 7”, I always wonder why ?.

  • But when I apply in the code, what is the following order for the byte st [0] = bit 7 or bit 1?

  • Also according to this diagram, does every command that I send mean always will have a heading?

  • This is the code I tried by taking bit 1 as st [0], bit 2 as st 1 instead of Bit 7 as st [0]. To apply the Power off / on test.

    import java.io.*; import java.net.*; public class test { public static void main(String[] args) throws UnknownHostException, IOException { byte st[]=new byte[256]; st[0]=0x01; // get st[1]=0x02; // header 2 byte st[2]=0x02; // header length st[3]=0; // command byte st[4]=0; // reserved st[5]=0; st[6]=0; st[7]=0; st[8]=0x01; // power off st[9]=0x30; st[10]=0x01; st[11]=0x00; System.out.println(st); // Should this work, am i correct based on diagram? Socket s = new Socket("192.168.1.2", 49137); DataInputStream input = new DataInputStream(s.getInputStream()); DataOutputStream outToServer = new DataOutputStream(s.getOutputStream()); BufferedReader i = new BufferedReader(new InputStreamReader(s.getInputStream())); outToServer.write(st); String get; get = i.readLine(); System.out.println("FROM SERVER: " + get); s.close(); } 

    }

enter image description hereenter image description here

PS: How would you really do this? Each hex command is executed manually, this PDF file contains almost 100 commands, it will take a long time. Or do you manage them differently?

+4
source share
3 answers
  • In this heading block, the charts are mainly displayed as "Bit 7, Bit 6, .., Bit 0", instead of "bit 0, bit 1, bit 2, ... bit 7", I always wonder why ?.

In a typical letter of the number 0, the least significant bit 7 is the most significant, and the byte is written in the most significant value to the lowest value 7-0.

 byte 11111111 place 76543210 
  • But when I apply in the code, what is the following order for the byte st [0] = bit 7 or bit 1?

In your code, this does not set bits, it sets a byte in an array of bytes

If you're nervous about setting the bits, try a class like this:

 public class SimpleByteSetter { /* b is is byte you are setting on is if the bit is set to on or 1 place is the bit place in the range of 0-7 */ public static byte set(final byte b, final boolean on, final int place) { if (on) { return (byte) (b | ((1 << place) & 0xFF)); } return (byte) (b & (~((1 << place) & 0xFF))); } // 1 == on everything else off (but only use 0!) public static byte set(final byte b, final int on, final int place) { return set(b, 1==on, place); } } 

use it in your code, for example:

 byte header = 0; // get = 0, set = 1, place = 0 header = SimpleByteSetter(header, 0, 0 ); // get // header 2 byte = 0, header 2 byte = 1, place = 1 header = SimpleByteSetter(header, 0, 1 ); // header 1 byte ... st[0] = header; 
  • Also, according to this diagram, does this mean that every command sent will always capture a header

Yes

  • This is the code I tried by taking bit 1 as st [0], bit 2 as st1 instead of bit 7 as st [0]. To apply the Power off / on test.

I do not have enough information to create a package, but:

 // the header is 1 byte I don't see how to make it two // the command is 2 bytes per the table // the parameter length is 0 so 1 byte (is there suppose to be a device id?) byte[] st = new byte[ 1 + 2 + 1 ]; byte header = 0; // get = 0, set = 1, place = 0 header = SimpleByteSetter(header, 0, 0 ); // get // header 2 byte = 0, header 2 byte = 1, place = 1 header = SimpleByteSetter(header, 0, 1 ); // header 1 byte // length 1 byte = 0, length 2 byte = 1 header = SimpleByteSetter(header, 0, 2 ); // command 1 byte = 0, command 2 byte = 1; header = SimpleByteSetter(header, 1, 3 ); st[0] = header; st[1] = 0x0130 & 0xFF; // poweroff command first byte st[2] = 0x0100 & 0xFF; // poweroff second byte st[3] = 0; 
+2
source

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.

+8
source

You do not need to worry about the order of the bits, since IP packets contain bytes, and lower-level components ensure that each byte is transmitted correctly.

Instead of System.out.println (st) I would make a small method that perfectly prints the command buffer in hexadeciaml.

+2
source

All Articles