【发布时间】:2015-06-19 01:46:01
【问题描述】:
我正在开发一个项目,我正在编写一个 Java 客户端,该客户端使用 TCP 通过 SSL 连接与服务进行通信。该服务以网络字节顺序(大端)将所有消息写入客户端字段,并以 UTF-8 编码文本。客户端也是如此。
客户端必须创建以发送到服务的消息格式如下所示
| 0 | 1 | 2 | 3 |
|------------------------------------------------|
| Header Version | Message Type |
|------------------------------------------------|
| Message Length |
|------------------------------------------------|
| Initial Timestamp |
|------------------------------------------------|
| Future use | Request Flags |
|------------------------------------------------|
- 标头版本 - 无符号 16 位 - 值始终为 1
- 消息类型 - 无符号 16 位
- 消息长度 - 无符号 32 位
- 初始时间戳 - 无符号 32 位
- 保留 - 无符号 16 位 - 始终设置为 0
- 请求标志 - bits[16]
如何在 Java 中使用无符号整数创建这种数据结构?
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer ;
public class NullMessage {
private final int BASE_HEADER_SIZE = 7;
int _headerVersion;
int _messageType;
long _messageLength;
byte[] _options;
public NullMessage( byte[] format ) {
if (format.length == BASE_HEADER_SIZE) {
_headerVersion = (int)( ( ( format[0] << 8 ) & 652080 ) | ( format[1 ] & 255 ));
_messageType = (int)( ( ( format[2] << 8 ) & 652080 ) | ( format[3] & 255 ));
_messageLength = (long)(((format[4]<<24)&4278190080l)
|((format[5]<<16)&16711680l)
|((format[6]<<8)&65280)
|(format[7]&255));
}
else {
throw new RuntimeException("Error in creating NullMessage format");
}
}
public int length() {
return BASE_HEADER_SIZE + (this._options == null ? 0 : this._options.length );
}
public NullMessage( int headerVersion, int messageType, long messageLength) {
this._headerVersion = headerVersion;
this._messageType = messageType;
this._messageLength = messageLength;
}
public byte[] toByteArray() {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
out.write( getHeader() );
if ( _options != null ){
out.write( this._options );
}
} catch (IOException e) {
System.out.println( e.toString() ) ;
}
return out.toByteArray() ;
}
// Generate the NullMessage in a byte array format
public byte[] getHeader() {
byte[] nullMessage = new byte[BASE_HEADER_SIZE];
nullMessage[0] = (byte)((_headerVersion>>8)&255);
nullMessage[1] = (byte)((_headerVersion&255));
nullMessage[2] = (byte)((_messageType>>8)&255);
nullMessage[3] = (byte)((_messageType&255));
nullMessage[3] = (byte)((_messageLength>>24)&255);
nullMessage[4] = (byte)((_messageLength>>16)&255);
nullMessage[5] = (byte)((_messageLength>>8)&255);
nullMessage[6] = (byte)((_messageLength&255));
return nullMessage;
}
public byte[] getOption() {
return _options;
}
public int getHeaderVersion() {
return this._headerVersion;
}
public void setHeaderVersion(int version) {
this._headerVersion = version;
}
public int getMessageType() {
return this._messageType;
}
public void setMessageType(int messageType ) {
this._messageType = messageType;
}
public long getMessageLength() {
return this._messageLength;
}
public void setMessageLength( long messageLength ) {
this._messageLength = messageLength;
}
public void print() {
byte[] head = getHeader();
for (int j=0; j<head.length; j++) {
System.out.format("%08X ", head[j]);
}
System.out.println();
}
public static void main(String args[]){
NullMessage test = new NullMessage(1, 0, 0);
test.print();
byte[] array = test.toByteArray();
for (int i=0;i<array.length;i++) {
System.out.println("myByte["+i+"]:"+ Integer.toBinaryString(array[i] & 255 | 256).substring(1));
}
}
}
【问题讨论】:
-
邮件内容呢?您是否希望收到相同格式的回复消息?时间戳格式到底是什么?
-
时间戳字段是一个 unix 时间戳值(自 1970 年 1 月 1 日以来的秒数。
-
返回的消息格式不同。仍在整理返回消息格式的细节
-
既然您已经发布了代码,请解释您遇到的问题。示例:样本输入、预期输出与实际输出。
-
查看我关于如何将字节放入 ByteBuffer 并将值提取到标头中的更新答案。