private TrackerInfo doRequest( String announce, String infoHash, String peerID, long uploaded, long downloaded, long left, String event) throws IOException { String s = announce + "?info_hash=" + infoHash + "&peer_id=" + peerID + "&port=" + port + "&uploaded=" + uploaded + "&downloaded=" + downloaded + "&left=" + left + ((event != NO_EVENT) ? ("&event=" + event) : ""); URL u = new URL(s); if (Snark.debug >= Snark.INFO) Snark.debug("Sending TrackerClient request: " + u, Snark.INFO); URLConnection c = u.openConnection(); c.connect(); InputStream in = c.getInputStream(); if (c instanceof HttpURLConnection) { // Check whether the page exists int code = ((HttpURLConnection) c).getResponseCode(); if (code / 100 != 2) // We can only handle 200 OK responses throw new IOException( "Loading '" + s + "' gave error code " + code + ", it probably doesn't exists"); } TrackerInfo info = new TrackerInfo(in, coordinator.getID(), coordinator.getMetaInfo()); if (Snark.debug >= Snark.INFO) Snark.debug("TrackerClient response: " + info, Snark.INFO); lastRequestTime = System.currentTimeMillis(); String failure = info.getFailureReason(); if (failure != null) throw new IOException(failure); interval = info.getInterval() * 1000; return info; }
public TrackerClient(MetaInfo meta, PeerCoordinator coordinator, int port) { // Set unique name. super("TrackerClient-" + urlencode(coordinator.getID())); this.meta = meta; this.coordinator = coordinator; // XXX - No way to actaully give the tracker feedback that we // don't run a peer acceptor on any port so use discard 9/tcp sink null this.port = (port == -1) ? 9 : port; stop = false; }
public void run() { // XXX - Support other IPs String announce = meta.getAnnounce(); String infoHash = urlencode(meta.getInfoHash()); String peerID = urlencode(coordinator.getID()); long uploaded = coordinator.getUploaded(); long downloaded = coordinator.getDownloaded(); long left = coordinator.getLeft(); boolean completed = (left == 0); try { boolean started = false; while (!started) { try { // Send start. TrackerInfo info = doRequest(announce, infoHash, peerID, uploaded, downloaded, left, STARTED_EVENT); Iterator it = info.getPeers().iterator(); while (it.hasNext()) coordinator.addPeer((Peer) it.next()); started = true; } catch (IOException ioe) { // Probably not fatal (if it doesn't last to long...) Snark.debug( "WARNING: Could not contact tracker at '" + announce + "': " + ioe, Snark.WARNING); } if (!started && !stop) { Snark.debug(" Retrying in one minute...", Snark.DEBUG); try { // Sleep one minutes... Thread.sleep(60 * 1000); } catch (InterruptedException interrupt) { // ignore } } } while (!stop) { try { // Sleep some minutes... Thread.sleep(SLEEP * 60 * 1000); } catch (InterruptedException interrupt) { // ignore } if (stop) break; uploaded = coordinator.getUploaded(); downloaded = coordinator.getDownloaded(); left = coordinator.getLeft(); // First time we got a complete download? String event; if (!completed && left == 0) { completed = true; event = COMPLETED_EVENT; } else event = NO_EVENT; // Only do a request when necessary. if (event == COMPLETED_EVENT || coordinator.needPeers() || System.currentTimeMillis() > lastRequestTime + interval) { try { TrackerInfo info = doRequest(announce, infoHash, peerID, uploaded, downloaded, left, event); Iterator it = info.getPeers().iterator(); while (it.hasNext()) coordinator.addPeer((Peer) it.next()); } catch (IOException ioe) { // Probably not fatal (if it doesn't last to long...) Snark.debug( "WARNING: Could not contact tracker at '" + announce + "': " + ioe, Snark.WARNING); } } } } catch (Throwable t) { Snark.debug("TrackerClient: " + t, Snark.ERROR); t.printStackTrace(); } finally { try { TrackerInfo info = doRequest(announce, infoHash, peerID, uploaded, downloaded, left, STOPPED_EVENT); } catch (IOException ioe) { /* ignored */ } } }