Question

Im planning to deploy a version for some IETF drafts and need some code references or guidance. Im familiar with basic TCP sockets but want to know how to translate requirements into code.

Example: Format for the Session Initiation Protocol (SIP) Common Log Format (CLF)

Would like to see how to translate:

 0          7 8        15 16       23 24         31
  +-----------+-----------+-----------+-----------+
  |  Version  |           Record Length           | 0 - 3
  +-----------+-----------+-----------+-----------+

   Version (1 byte):  0x41 for this document; hexadecimal encoded.

   Record Length (6 bytes):  Hexadecimal encoded total length of this
  log record, including "Flags" and "Record Length" fields, and
  terminating line-feed.

into code. How can I define Version? Which type? Int, char, etc?

Thanks

Was it helpful?

Solution

Instead of writing it from scratch, I would suggest to use applications like Jboss Netty , Apache Mina or Grizzly. They are specifically targeted for high performance protocol development.

Here is an example of Grizzly being used for Supporting SIP.

OTHER TIPS

Your primary tool will be DataOutputStream. It handles all the primitive types and takes care of network byte ordering for you as well. DataInputStream at the receiver. Your Version field would be written with write().

You'll run into some problems because Java doesn't include any unsigned types, you might also run into issues with endianness (Java is always big-endian). If a protocol specification stipulates that a 16-bit unsigned integer field exists then you'd hold the value in a 32-bit signed integer and write out (or read) the raw bytes to/from Network streams on a per-byte basis. Note that InputStream's read() method returns individual bytes as int values.

Here's how I'd read your example:

InputStream stream = getNetworkInputStream();
int version = stream.read();

int recordLength0 = stream.read();
int recordLength1 = stream.read();
int recordLength2 = stream.read();
int recordLength3 = stream.read();

long recordLength = recordLength0 << 24 | recordLength1 << 16 | recordLength2 << 8 | recordLength; // perform the bitwise OR of all four values

Writing is slightly more painful. Be careful if you do use the byte type internally as it is signed.

int version; long recordLength;

OutputStream stream = getNetworkOutputStream();
stream.write( version ); // the write(int) method only writes the low 8 bits of the integer value and ignores the high 24 bits.

stream.write( recordLength >> 24 ); // shift the recordLength value to the right by 8 bits
stream.write( recordLength >> 16 );
stream.write( recordLength >>  8 );
stream.write( recordLength       );

Use ByteBuffer for converting the bytes into individual variables. It can deal with byte order for you.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top