Update # 4: java demo added to work with UDP and send msg message (remember that the connection is the first!) Check your own answer below.
==================================================== ==
Update # 3: I managed to get it working, the doConnect () method is presented below, more information in my own answer below.
==================================================== ==
I am mainly interested in how to download tracker response when url announcement protocol is UDP.
Details: Thus, these are some announcements of announcements from a valid torrent file (the first of them is the main one)
http://tracker.torrentbox.com:2710/announce udp://elbitz.net:80/announce.php?passkey=362fc69de3402e8ef5794c7ecf7c58d4 udp://tracker.podtropolis.com:2711/announce
If the protocol is HTTP, everything is going well, and this is how I work:
String fullUrl = announceURL + "?info_hash=" + this.m_TorrentInfoHashAsURL + ..
If the protocol is UDP, the URL constructor throws "java.net.MalformedURLException: unknown protocol: udp"
So, I think that the problem can be resumed until the following: how to download a response from a URL via UDP? (hope this is simple, and I don't see any datagram thing)
UPDATE # 1:
I did some more research on the Internet and came to the following structure inserted below (should work .. but that doesnβt mean, I mean locally, but not with a real tracker)
reference to technical specifications: http://www.bittorrent.org/beps/bep_0015.html
Ex: This is how I create the socket, but on the actual tracker I never get anything back as an answer, so something does not work:
if full url: udp://elbitz.net:80/announce.php?passkey=362fc69de3402e8ef5794c7ecf7c58d4 this.m_TrackerHost: elbitz.net this.m_TrackerPort: 80 private DatagramSocket m_WorkingSocket; private DatagramSocket getWorkingSocket() { Logger.d(TAG, "getWorkingSocket()"); if(this.m_WorkingSocket==null){ Random rnd = new Random(); for (int i = 0; i < 100; i++) { try { int port = 15000 + rnd.nextInt(15000); // [15000-30000) DatagramSocket result = new DatagramSocket(port); InetAddress trackerAddress = InetAddress.getByName(this.m_TrackerHost); result.connect(trackerAddress, this.m_TrackerPort); this.m_WorkingSocket = result; } catch (SocketException se) { Logger.w(TAG, "getWorkingSocket() - port is taken"); } catch (SecurityException se) { Logger.w(TAG, "getWorkingSocket() - port is blocked?"); } catch (UnknownHostException e) { Logger.w(TAG, "getWorkingSocket() - unkwnown host?"); } } } return this.m_WorkingSocket; }
& now the full code from doConnect, which should be the first phase of communication (the next is the announcement .. similar code there)
private boolean doConnect() throws IOException{ Logger.d(TAG, "doConnect()"); DatagramSocket workingSocket = this.getWorkingSocket(); DatagramPacket sendPacket = null, receivePacket = null; byte[] sendData = null; byte[] receiveData = null; int round = 0; Logger.d(TAG, "doConnect(): first round, timeout: " + this.getTimeoutInMillis(ACTION_ID_CONNECT, round)); while(true) { if(round==8){ Logger.w(TAG, "doConnect() - failed to connect with tracker, consumed in vain all 8 rounds.."); return false; } workingSocket.setSoTimeout(this.getTimeoutInMillis(ACTION_ID_CONNECT, round)); if(receivePacket==null){ receiveData = new byte[16];
The problem remains. I never get a response from the tracker (I also tried with a different URL) A new question: is it normal to create a socket on elbitz.net, port: 80, when the full url contains more information (for example: / announcement)?
Update # 2
The code above seems to work fine .. I found on google a list of trackers that implemented this specification, and voila answered (for example: "udp: //tracker.openbittorrent.com: 80")
A new question over and over here: http://www.bittorrent.org/beps/bep_0015.html - It seems I donβt see how to get a list of peers? .. in the usual request to the torrent tracker (via http) there were 2 cases: a normal response (a card with bencoded) and a compressed response (in binary form). So, was there a peer list now?
- from the specification this is the announcement response:
/* Offset Size Name Value 0 32-bit integer action 1 // announce 4 32-bit integer transaction_id 8 32-bit integer interval 12 32-bit integer leechers 16 32-bit integer seeders 20 + 6 * n 32-bit integer IP address 24 + 6 * n 16-bit integer TCP port 20 + 6 * N */
from my tests, I always get the same values ββfor the fields: IP address and TCP port .. plus that I get one response per request .. so CANT BE IT! .. I need a peer list!
Please, help! the only types of response messages that I implemented are still scratches and errors ... but no one contains the information that interests me (peer information: ip and port) ex: scrape
Offset Size Name Value 0 32-bit integer action 2 // scrape 4 32-bit integer transaction_id 8 + 12 * n 32-bit integer seeders 12 + 12 * n 32-bit integer completed 16 + 12 * n 32-bit integer leechers 8 + 12 * N