【发布时间】:2018-08-10 20:06:43
【问题描述】:
我在尝试创建网络字节标头时遇到了一些麻烦。 header 应该是 2 个字节长,它简单地定义了以下命令的长度。
例如;以下命令字符串"HED>0123456789ABCDEF" 长度为 20 个字符,即0014 为十六进制带符号的 2 补码,为该命令创建网络字节头的工作原理是该命令少于 124 个字符。下面的 sn-p 代码本质上是计算出字节头,并在命令少于 124 个字符时将以下前缀添加到命令 \u00000\u0014。
但是对于 124 个字符或以上的命令,if 块中的代码不起作用。因此,我研究了可能的替代方案,并尝试了一些关于生成十六进制字符并将它们设置为网络字节头的方法,但由于它们不是字节,所以它不起作用(如 else 块中所示)。相反,else 块仅返回 0090 以获取 153 字符长的命令,这在技术上是正确的,但我无法像 if 块长度头一样使用这个“长度”头
public static void main(String[] args) {
final String commandHeader = "HED>";
final String command = "0123456789ABCDEF";
short commandLength = (short) (commandHeader.length() + command.length());
char[] array;
if( commandLength < 124 )
{
final ByteBuffer bb = ByteBuffer.allocate(2).putShort(commandLength);
array = new String( bb.array() ).toCharArray();
}
else
{
final ByteBuffer bb = ByteBuffer.allocate(2).putShort(commandLength);
array = convertToHex(bb.array());
}
final String command = new String(array) + commandHeader + command;
System.out.println( command );
}
private static char[] convertToHex(byte[] data) {
final StringBuilder buf = new StringBuilder();
for (byte b : data) {
int halfByte = (b >>> 4) & 0x0F;
int twoHalves = 0;
do {
if ((0 <= halfByte) && (halfByte <= 9))
buf.append((char) ( '0' + halfByte));
halfByte = b & 0x0F;
} while (twoHalves++ < 1);
}
return buf.toString().toCharArray();
}
此外,通过执行以下三行代码,我已经成功地在 Python 2 中实现了这一点!这将为 153 个字符的命令返回以下网络字节标头 \x00\x99
msg_length = len(str_header + str_command)
command_length = pack('>h', msg_length)
command = command_length + str_header + str_command
也可以通过运行 Python 2 并输入以下命令进行简单复制:
In [1]: import struct
In [2]: struct.pack('>h', 153)
Out[2]: '\x00\x99'
非常感谢任何可以解决此问题的帮助或提示。
【问题讨论】:
-
您的消息本质上是一个 byte 序列。为什么要将其转换为字符序列? (在您的特定情况下为
String,但char[]、StringBuilder或Reader不会更好。) -
我们是否应该评估 Java 代码,就好像它没有明确区分
if( commandLength < 124 )和替代代码一样? -
@JohnBollinger 对不起,如果我没有说清楚,我已经编辑了 sn-ps 以更好地反映 Java 代码,并稍微更新了描述
标签: java python sockets byte short