我打算为某些IETF草案部署一个版本,需要一些代码参考或指导。我熟悉基本的TCP套接字,但想知道如何将需求转换为代码。
示例:Format for the Session Initiation Protocol (SIP) Common Log Format (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.
代码。 我该如何定义版本? 哪种类型? Int,char等?
由于
答案 0 :(得分:2)
您的主要工具是DataOutputStream
。它处理所有原始类型,并为您处理网络字节排序。 DataInputStream
在收件人处。您的Version
字段将使用write()
编写。
答案 1 :(得分: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 );
答案 2 :(得分:1)
使用ByteBuffer将字节转换为单个变量。它可以为你处理字节顺序。
答案 3 :(得分:1)
我建议使用Jboss Netty,Apache Mina或Grizzly之类的应用,而不是从头开始编写。它们专门用于高性能协议开发。
Grizzly的Here is an example被用于支持SIP。