1

我计划为一些 IETF 草案部署一个版本,并且需要一些代码参考或指导。我熟悉基本的 TCP 套接字,但想知道如何将需求转换为代码。

示例:会话发起协议 (SIP) 通用日志格式 (CLF) 的格式

想看看怎么翻译:

 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.

成代码。如何定义版本?哪种类型?整数,字符等?

谢谢

4

4 回答 4

2

您的主要工具将是DataOutputStream. 它处理所有原始类型并为您处理网络字节排序。DataInputStream在接收器处。您的Version字段将使用write().

于 2012-09-07T01:35:55.217 回答
2

您会遇到一些问题,因为 Java 不包含任何无符号类型,您也可能会遇到字节序问题(Java 始终是大字节序)。如果协议规范规定存在一个 16 位无符号整数字段,那么您会将值保存在一个 32 位有符号整数中,并按每个字节将原始字节写入(或读取)网络流。请注意,InputStream 的read()方法将单个字节作为int值返回。

这是我阅读您的示例的方式:

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

写作稍微痛苦一些。byte如果您确实在内部使用该类型,因为它已签名,请小心。

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       );
于 2012-09-07T01:36:05.483 回答
1

使用ByteBuffer将字节转换为单个变量。它可以为您处理字节顺序。

于 2012-09-07T01:39:31.290 回答
1

我建议不要从头开始编写,而是使用Jboss NettyApache MinaGrizzly等应用程序。它们专门针对高性能协议开发。

这是一个用于支持 SIP 的 Grizzly示例。

于 2012-09-07T05:00:19.383 回答