2017-08-15 192 views
1

我將來自router.bittorrent.com的find_node響應的節點解碼爲字符串,並向解碼的「節點」發送了find_node請求,但是我從未修改過來自該「節點」的find_node響應,我懷疑解碼「節點」是錯誤的,這是代碼:如何解碼java中的緊湊節點信息?

 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 ""; 
} 

任何問題嗎?

PS: send()函數運行良好。

回答

0

((String)nodes).getBytes();

即假定一個特定的編碼,這可能不適合於這種情況下。這取決於你使用的bdecoder實現。理想情況下,你應該使用返回直接從B編碼後的數據byte[]ByteBuffer的方法,而不需要通過String

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

您應該使用|而不是+。另外short是java中的一種簽名類型,但端口號在0-65535的無符號範圍內,所以應該擴展爲int。 而網絡格式是bigendian,所以端口的最高有效位位於第一個字節的第0個字節和下半部分,所以您也得到了相反的結果。

使用ByteBuffer代替byte[]像我這樣in my own implementation可以使這個遠不如容易出錯,因爲它可以讓你直接得到一個簡短,然後將其轉換爲一個unsigned int。

+0

我更新瞭解碼字符串 –

+0

我看不出有什麼關係。它甚至沒有在你的代碼中調用,也沒有解決我所說的任何事情。代碼中的可識別問題是bdecoding(字符串與字節緩衝區),字節序轉換和位操作。 – the8472