Torrent 管理:UDP 协议错误
Torrent Management: error with protocol UDP
我正在尝试使用 jlibitorrent 库在 java 中开发一个 torrent 管理器,但是当执行该程序时我收到以下错误:
Bencoding Exception:
unknown protocol: udp
at com.torrent.util.TorrentInfo.(TorrentInfo.java:160)
at st.ST.main(ST.java:70)
程序的参数是从网上下载的torrent,传输也可以。
给我报错信息的函数代码是:
@SuppressWarnings("unchecked")
public TorrentInfo(byte[] torrent_file_bytes) throws BencodingException
{
// Make sure the input is valid
if(torrent_file_bytes == null || torrent_file_bytes.length == 0)
throw new IllegalArgumentException("Torrent file bytes must be non-null and have at least 1 byte.");
// Assign the byte array
this.torrent_file_bytes = torrent_file_bytes;
// Assign the metainfo map
this.torrent_file_map = (Map<ByteBuffer,Object>)Bencoder2.decode(torrent_file_bytes);
// Try to extract the announce URL
ByteBuffer url_buff = (ByteBuffer)this.torrent_file_map.get(TorrentInfo.KEY_ANNOUNCE);
if(url_buff == null)
throw new BencodingException("Could not retrieve anounce URL from torrent metainfo. Corrupt file?");
try {
String url_string = new String(url_buff.array(), "ASCII");
URL announce_url = new URL(url_string);
this.announce_url = announce_url;
}
catch(UnsupportedEncodingException uee)
{
throw new BencodingException(uee.getLocalizedMessage());
}
catch(MalformedURLException murle)
{
throw new BencodingException(murle.getLocalizedMessage());
}
// Try to extract the info dictionary
ByteBuffer info_bytes = Bencoder2.getInfoBytes(torrent_file_bytes);
Map<ByteBuffer,Object> info_map = (Map<ByteBuffer,Object>)this.torrent_file_map.get(TorrentInfo.KEY_INFO);
if(info_map == null)
throw new BencodingException("Could not extract info dictionary from torrent metainfo dictionary. Corrupt file?");
this.info_map = info_map;
// Try to generate the info hash value
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(info_bytes.array());
byte[] info_hash = digest.digest();
this.info_hash = ByteBuffer.wrap(info_hash);
}
catch(NoSuchAlgorithmException nsae)
{
throw new BencodingException(nsae.getLocalizedMessage());
}
// Extract the piece length from the info dictionary
Integer piece_length = (Integer)this.info_map.get(TorrentInfo.KEY_PIECE_LENGTH);
if(piece_length == null)
throw new BencodingException("Could not extract piece length from info dictionary. Corrupt file?");
this.piece_length = piece_length.intValue();
// Extract the file name from the info dictionary
ByteBuffer name_bytes = (ByteBuffer)this.info_map.get(TorrentInfo.KEY_NAME);
if(name_bytes == null)
throw new BencodingException("Could not retrieve file name from info dictionary. Corrupt file?");
try {
this.file_name = new String(name_bytes.array(),"ASCII");
}
catch(UnsupportedEncodingException uee)
{
throw new BencodingException(uee.getLocalizedMessage());
}
// Extract the file length from the info dictionary
Integer file_length = (Integer)this.info_map.get(TorrentInfo.KEY_LENGTH);
if(file_length == null)
throw new BencodingException("Could not extract file length from info dictionary. Corrupt file?");
this.file_length = file_length.intValue();
// Extract the piece hashes from the info dictionary
ByteBuffer all_hashes = (ByteBuffer)this.info_map.get(TorrentInfo.KEY_PIECES);
if(all_hashes == null)
throw new BencodingException("Could not extract piece hashes from info dictionary. Corrupt file?");
byte[] all_hashes_array = all_hashes.array();
// Verify that the length of the array is a multiple of 20 bytes (160 bits)
if(all_hashes_array.length % 20 != 0)
throw new BencodingException("Piece hashes length is not a multiple of 20. Corrupt file?");
int num_pieces = all_hashes_array.length / 20;
// Copy the values of the piece hashes into the local field
this.piece_hashes = new ByteBuffer[num_pieces];
for(int i = 0; i < num_pieces; i++)
{
byte[] temp_buff = new byte[20];
System.arraycopy(all_hashes_array,i*20,temp_buff,0,20);
this.piece_hashes[i] = ByteBuffer.wrap(temp_buff);
}
}
}
我看了两天代码,不知道哪里出错了,非常感谢大家的帮助。谢谢
Torrents 可以包含 udp://...
宣布用于 UDP trackers 的 URLs。虽然方案名称有点过于通用,但事实就是如此。
默认情况下,Java 的 URL class 无法处理这些。有关可能的解决方案,请参阅 this SO question。
有人可能会争辩说这是库中的一个错误,因为它不仅仅是 return 一个字符串,因此 Torrent 解码不会仅仅因为格式错误或未知的 URI 而中止。实现在他们接受的内容上应该是自由的(在合理范围内),所以在这种情况下,他们应该简单地过滤掉他们无法处理的 URI 方案。
我正在尝试使用 jlibitorrent 库在 java 中开发一个 torrent 管理器,但是当执行该程序时我收到以下错误:
Bencoding Exception: unknown protocol: udp at com.torrent.util.TorrentInfo.(TorrentInfo.java:160) at st.ST.main(ST.java:70)
程序的参数是从网上下载的torrent,传输也可以。
给我报错信息的函数代码是:
@SuppressWarnings("unchecked")
public TorrentInfo(byte[] torrent_file_bytes) throws BencodingException
{
// Make sure the input is valid
if(torrent_file_bytes == null || torrent_file_bytes.length == 0)
throw new IllegalArgumentException("Torrent file bytes must be non-null and have at least 1 byte.");
// Assign the byte array
this.torrent_file_bytes = torrent_file_bytes;
// Assign the metainfo map
this.torrent_file_map = (Map<ByteBuffer,Object>)Bencoder2.decode(torrent_file_bytes);
// Try to extract the announce URL
ByteBuffer url_buff = (ByteBuffer)this.torrent_file_map.get(TorrentInfo.KEY_ANNOUNCE);
if(url_buff == null)
throw new BencodingException("Could not retrieve anounce URL from torrent metainfo. Corrupt file?");
try {
String url_string = new String(url_buff.array(), "ASCII");
URL announce_url = new URL(url_string);
this.announce_url = announce_url;
}
catch(UnsupportedEncodingException uee)
{
throw new BencodingException(uee.getLocalizedMessage());
}
catch(MalformedURLException murle)
{
throw new BencodingException(murle.getLocalizedMessage());
}
// Try to extract the info dictionary
ByteBuffer info_bytes = Bencoder2.getInfoBytes(torrent_file_bytes);
Map<ByteBuffer,Object> info_map = (Map<ByteBuffer,Object>)this.torrent_file_map.get(TorrentInfo.KEY_INFO);
if(info_map == null)
throw new BencodingException("Could not extract info dictionary from torrent metainfo dictionary. Corrupt file?");
this.info_map = info_map;
// Try to generate the info hash value
try {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(info_bytes.array());
byte[] info_hash = digest.digest();
this.info_hash = ByteBuffer.wrap(info_hash);
}
catch(NoSuchAlgorithmException nsae)
{
throw new BencodingException(nsae.getLocalizedMessage());
}
// Extract the piece length from the info dictionary
Integer piece_length = (Integer)this.info_map.get(TorrentInfo.KEY_PIECE_LENGTH);
if(piece_length == null)
throw new BencodingException("Could not extract piece length from info dictionary. Corrupt file?");
this.piece_length = piece_length.intValue();
// Extract the file name from the info dictionary
ByteBuffer name_bytes = (ByteBuffer)this.info_map.get(TorrentInfo.KEY_NAME);
if(name_bytes == null)
throw new BencodingException("Could not retrieve file name from info dictionary. Corrupt file?");
try {
this.file_name = new String(name_bytes.array(),"ASCII");
}
catch(UnsupportedEncodingException uee)
{
throw new BencodingException(uee.getLocalizedMessage());
}
// Extract the file length from the info dictionary
Integer file_length = (Integer)this.info_map.get(TorrentInfo.KEY_LENGTH);
if(file_length == null)
throw new BencodingException("Could not extract file length from info dictionary. Corrupt file?");
this.file_length = file_length.intValue();
// Extract the piece hashes from the info dictionary
ByteBuffer all_hashes = (ByteBuffer)this.info_map.get(TorrentInfo.KEY_PIECES);
if(all_hashes == null)
throw new BencodingException("Could not extract piece hashes from info dictionary. Corrupt file?");
byte[] all_hashes_array = all_hashes.array();
// Verify that the length of the array is a multiple of 20 bytes (160 bits)
if(all_hashes_array.length % 20 != 0)
throw new BencodingException("Piece hashes length is not a multiple of 20. Corrupt file?");
int num_pieces = all_hashes_array.length / 20;
// Copy the values of the piece hashes into the local field
this.piece_hashes = new ByteBuffer[num_pieces];
for(int i = 0; i < num_pieces; i++)
{
byte[] temp_buff = new byte[20];
System.arraycopy(all_hashes_array,i*20,temp_buff,0,20);
this.piece_hashes[i] = ByteBuffer.wrap(temp_buff);
}
}
}
我看了两天代码,不知道哪里出错了,非常感谢大家的帮助。谢谢
Torrents 可以包含 udp://...
宣布用于 UDP trackers 的 URLs。虽然方案名称有点过于通用,但事实就是如此。
Java 的 URL class 无法处理这些。有关可能的解决方案,请参阅 this SO question。
有人可能会争辩说这是库中的一个错误,因为它不仅仅是 return 一个字符串,因此 Torrent 解码不会仅仅因为格式错误或未知的 URI 而中止。实现在他们接受的内容上应该是自由的(在合理范围内),所以在这种情况下,他们应该简单地过滤掉他们无法处理的 URI 方案。