quinestor
quinestor

Reputation: 1442

Get hex values from socket and convert to decimal

I have data that I read from a socket and I know it has the following format:

[2bytes][8bytes][2bytes] = 12 bytes

That I want to read separately; and the values are in Hex. I actually captured that data a while ago in PHP and saved it to files and I can view it properly using od (unix):

$ od -h myFile
$ 0000000 02eb 02fe fe02 fefe 02fe 02fe 000a
$ 0000015 

That, has a CR and LF at the end, resulting in 14 bytes. How can I obtain those values in Java reading from a socket? For instance how do I get that "02eb" (2 bytes) and convert it to a decimal value?

I am already reading from the socket, last thing I tried was:

mMessage = mBRin.readLine();
byte[] bytes = mMessage.trim().getBytes()

But that gives me 18 bytes in the array.

If it helps, in PHP to get that first part I did:

$input = socket_read($value,13,PHP_BINARY_READ);
$trim_input = trim($input);
$float_head = hexdec(bin2hex(substr($input,0,2)));

I think I am not understanding this, which may be the answer

Upvotes: 1

Views: 2583

Answers (2)

Guido Simone
Guido Simone

Reputation: 7952

I have data that I read from a socket and I know it has the following format:

[2bytes][8bytes][2bytes] = 12 bytes

If you already have code to read bytes from a socket, you can use a ByteBuffer to convert the bytes to short, int, long etc. values.

Socket s = .....;

InputStream in = s.getInputStream();
byte [] buf = new byte[12];

// read 12 bytes from socket into bytes
in.read(buf);

ByteBuffer bb = ByteBuffer.allocate(buf.length);
bb.order(ByteOrder.LITTLE_ENDIAN);
bb.put(buf);
bb.flip();
short short1 = bb.getShort();
long long1 = bb.getLong();
short short2 = bb.getShort();

Note the call to set the byte buffer to little endian.

When you did the od command you got output similar to the following (this output comes from a file I created on my system to mimic yours). The od -h command reads the bytes from the file, puts them together as 2-byte shorts in little endian mode then prints out the short values in hex.

$ od -h binary.dat 
0000000      02eb    02fe    fe02    fefe    02fe    02fe    000a        
0000015

However if you use the -tx1 you see the bytes in the real order they appear in the file.

$ od -tx1 binary.dat
$ 0000000    eb  02  fe  02  02  fe  fe  fe  fe  02  fe  02  0a
$ 0000015

If you run this on your file I think you will see that it is really 13 bytes not 14 bytes and is terminated by a single LF, not CRLF. The "extra" byte you saw was a "present" from od -h is does not actually exist in file.

Anyhow, The first byte is value 235 (EB in hex). The second byte is 2. The question is - what is the correct value for that first short want. If, according to your socket protocol, the data is serialized in little endian mode, the value of those two bytes concatenated into a short is 02EB hex or 747. If the socket protocol uses big endian, then the value is EB02 hex or 60162.

The ByteBuffer approach gives you flexibility and allows you to read/write in either big-endian or little endian. It also allows you to separate the reading of data off the socket (into byte arrays) then later converting the data into numbers. This may make it easier for unit testing since you can create byte arrays for various test cases and make sure your parsing code works as expected.

The DataInputStream approach in sharadendu's answer will also work - but only if the socket protocol is big-endian. DataInputStream is hard-coded to big-endian.

Upvotes: 2

sharadendu sinha
sharadendu sinha

Reputation: 827

Socket socket = ......;
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        short f1 = dis.readShort();
        long f2 = dis.readLong();
        sort f3 = dis.readShort();

To print the values in hex use String.format("%x",f1); Hope it helps ...

Upvotes: 2

Related Questions