Network Byte Order ...

L

Luke Skywalker

hi all :)

I have to read a network packet, coded by a C program, where
the first two bytes codes the packet type, the following four
the packet length and then the payload. My problem is that the
lengths are integer coded (by the C program) into the network
order (using the htons() and htonl() functions). How can I perform
the decoding form Java? I.e. I read the first two byte:

int c1 = in.read();
int c2 = in.read();

How can I convert c1 and c1 into the packet length?

thanks in advance for ur reply !!!!! :)
 
G

Gordon Beaton

My problem is that the lengths are integer coded (by the C program)
into the network order (using the htons() and htonl() functions).

Network byte order is big endian. Use a DataInputstream; it has
methods to read various data types stored in big endian order.

Alternatively you can shift and add yourself, but this gets tedious:

int n = (c1 << 8) + c2;

/gordon
 
A

A. Craig West

Network byte order is big endian. Use a DataInputstream; it has
methods to read various data types stored in big endian order.

It is not a coincidence that 'network byte order' happens to coincide with
what Java uses in it's input and output. DataInputStream is the way to go,
and remember that all Java numeric types except char are signed. Java short's
are always 16 bits, int's are always 32 bits and long's are always 64 bits.

If your packet length is stored as a 16 bit value in network byte order, you
coulde read it like so:
try {
DataInputStream din = new DataInputStream(in);
short packetLength = din.readShort();
} catch (IOException ioe) {
// Do something to handle the exception
}
 
B

Babu Kalakrishnan

A. Craig West said:
It is not a coincidence that 'network byte order' happens to coincide with
what Java uses in it's input and output. DataInputStream is the way to go,
and remember that all Java numeric types except char are signed. Java short's
are always 16 bits, int's are always 32 bits and long's are always 64 bits.

If your packet length is stored as a 16 bit value in network byte order, you
coulde read it like so:
try {
DataInputStream din = new DataInputStream(in);
short packetLength = din.readShort();
} catch (IOException ioe) {
// Do something to handle the exception
}

Since packet lengths are generally unsigned, it would probably be better
to use :

int packetLength = din.readUnsignedShort();

BK
 
L

Luke Skywalker

Gordon Beaton said:
Alternatively you can shift and add yourself, but this gets tedious:

int n = (c1 << 8) + c2;

/gordon

thanks for ur help, Gordon ... you have been very kind!

best regards
 
L

Luke Skywalker

Gordon Beaton said:
Alternatively you can shift and add yourself, but this gets tedious:

int n = (c1 << 8) + c2;

/gordon

thanks for ur help, Gordon ... you have been very kind!

best regards
 
L

Luke Skywalker

Gordon Beaton said:
Alternatively you can shift and add yourself, but this gets tedious:

int n = (c1 << 8) + c2;

/gordon

thanks for ur help, Gordon ... you have been very kind!

best regards
 
S

Steve Horsley

nos said:
is it possible theoretically that c2 is a negative number?
Yes. You really need to mask the bytes as well:

int x = ((c1 & 255) << 8) | (c2 & 255);

Yuk! signed bytes.

Steve
 
B

Babu Kalakrishnan

Steve said:
Yes. You really need to mask the bytes as well:

int x = ((c1 & 255) << 8) | (c2 & 255);

Yuk! signed bytes.

That's true if c1 and c2 are bytes. But in the specific case that was
being discussed, these were declared as type int and are the results of
the read() method from an InputStream - which always returns an int
between 0 and 255. (Of course an end of stream case can return -1, but
then that is a special check that needs to be done for handling errors)

BK
 
S

Steve Horsley

Babu said:
That's true if c1 and c2 are bytes. But in the specific case that was
being discussed, these were declared as type int and are the results of
the read() method from an InputStream - which always returns an int
between 0 and 255. (Of course an end of stream case can return -1, but
then that is a special check that needs to be done for handling errors)

BK

Oops! You are right of course. Thank you.

Steve
 
S

Steve Horsley

nos said:
so the answer is yes, c2 can be negative
As Babu pointed out, it depends where c1 and c2 come from.
InputStream.read() returns an integer between 0 and 255, so they can not
be negative (except for the -1 that indicates EOF).

However, if you use InputStream.read(byte[]) then you end up with an
array of bytes with values in the range -128 to +127.

If you intend to use read(), it's probably best to wrap the InputStream
in a BufferedInputStream to reduce the number of O/S level I/O calls you
make.

Steve
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top