如何在java中解码紧凑节点信息?



我将find_node响应的节点从 router.bittorrent.com 解码为字符串,并向解码的"节点"发送了find_node请求,但我从未从该"节点"find_node响应,我怀疑解码"节点"的方式是错误的,这是代码:

byte[] nodesBytes = ((String)nodes).getBytes();
ByteBuffer buffer = ByteBuffer.wrap(nodesBytes);
int size = nodesBytes.length / 26;
for (int i = 0; i < size; i++) {
byte[] bytes = new byte[26];
byte[] nodeIdBytes = Arrays.copyOfRange(bytes, 0, 20);
byte[] ipBytes = Arrays.copyOfRange(bytes, 20, 24);
byte[] portBytes = Arrays.copyOfRange(bytes, 24, 26);
RoutingTable.RoutingNode routingNode = new RoutingTable.RoutingNode();
try {
routingNode.nodeId = nodeIdBytes;
routingNode.ip = InetAddress.getByAddress(ipBytes);
routingNode.port = (((((short)portBytes[1]) << 8) & 0xFF00) + (((short)portBytes[0]) & 0x00FF));
} catch (UnknownHostException e) {
e.printStackTrace();
}
send(routingNode);
}

解码字符串代码是

private static String decodeString(ByteBuffer byteBuffer) {
try {
StringBuilder buffer = new StringBuilder();
int type = byteBuffer.get();
buffer.append((char) type);
do {
byte a = byteBuffer.get();
if (a == SEPARATOR) {
break;
} else {
buffer.append((char) a);
}
} while (true);
int length = Integer.parseInt(buffer.toString());
byte[] bytes = new byte[length];
byteBuffer.get(bytes);
String value = new String(bytes, "UTF-8");
logger.debug(value);
return value;
} catch (Exception e) {
logger.error("", e);
}
return "";
}

有任何问题吗?

附注: send(( 函数运行良好。

((String)nodes).getBytes();

这假定使用特定的编码,这可能不适合这种情况。这取决于您使用的 bdecoder 实现的作用。理想情况下,应使用直接从编码数据返回byte[]ByteBuffer的方法,而不进行String

routingNode.port = (((((short)portBytes[1]) << 8) & 0xFF00) + (((short)portBytes[0]) & 0x00FF));

您应该使用|而不是+。此外,short是 Java 中的有符号类型,但端口在 0-65535 的无符号范围内,因此您应该扩展到int。 而且网络格式是bigendian,所以端口最重要的位在第0个字节和第1个字节的下半部分,所以你也得到了它。

使用ByteBuffer而不是像我在自己的实现中所做的那样byte[]可以使这更不容易出错,因为它允许您直接获取 short 然后将其转换为无符号的 int。

最新更新