Reputation: 1442
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
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
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