From 6821fd3e0f7df70df578c39a4e510859b0ec9200 Mon Sep 17 00:00:00 2001 From: Rogiel Date: Wed, 14 Sep 2011 23:59:50 -0300 Subject: [PATCH] Fix tracker support and update maven build script Fixed an issue with the tracker support in which it wansn't doing requests correctly and not updating the swarm list. Also adds support for assembling in maven. Now, each compilation will build generate an zip, tar.gz and tar.bz2 files with dependencies, binary and javadoc files. --- .classpath | 4 +- .gitignore | 1 + .project | 3 +- .settings/org.eclipse.jdt.core.prefs | 5 +- .settings/org.eclipse.m2e.core.prefs | 5 + pom.xml | 66 ++++++---- src/assembly/distribution-bin.xml | 33 +++++ .../java/net/torrent/BitTorrentClient.java | 39 +++++- .../algorithm/impl/TorrentStdAlgorithm.java | 15 ++- .../impl/TorrentStdInterestAlgorithm.java | 28 ++++- .../impl/TorrentStdPeerAlgorithm.java | 14 ++- .../TorrentStdPieceDownloadAlgorithm.java | 8 +- .../impl/TorrentStdPieceUploadAlgorithm.java | 9 +- .../algorithm/impl/TorrentTestAlgorithm.java | 65 ++++++++++ .../impl/TorrentTestInterestAlgorithm.java | 69 ++++++++++ .../impl/TorrentTestPeerAlgorithm.java | 73 +++++++++++ .../TorrentTestPieceDownloadAlgorithm.java | 118 ++++++++++++++++++ .../impl/TorrentTestPieceUploadAlgorithm.java | 47 +++++++ .../protocol/peerwire/PeerWirePeer.java | 46 +++++++ .../handler/PeerWireAlgorithmHandler.java | 69 ++++++++-- .../handler/PeerWireManagerHeadHandler.java | 22 ++-- .../handler/PeerWireManagerTailHandler.java | 25 ++++ .../peerwire/message/BitfieldMessage.java | 8 +- .../tracker/HttpTorrentTrackerAnnouncer.java | 16 ++- .../HttpTorrentTrackerPipelineFactory.java | 23 +++- .../protocol/tracker/TrackerHandler.java | 34 ++++- .../codec/ISO8859HttpRequestEncoder.java | 40 ------ .../tracker/codec/TorrentTrackerBDecoder.java | 7 +- .../tracker/message/AnnounceMessage.java | 21 ++-- .../tracker/message/PeerListMessage.java | 2 +- .../java/net/torrent/torrent/Torrent.java | 24 +++- .../torrent/torrent/context/TorrentPeer.java | 26 ++++ .../torrent/torrent/context/TorrentSwarm.java | 49 ++++++++ .../torrent/piece/ScoredPieceSelector.java | 1 - .../HttpTorrentTrackerAnnouncerTest.java | 40 ------ .../peerwire/PeerWireManagerTest.java | 27 +++- src/test/resources/logging.properties | 3 + 37 files changed, 907 insertions(+), 178 deletions(-) create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 src/assembly/distribution-bin.xml create mode 100644 src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestAlgorithm.java create mode 100644 src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestInterestAlgorithm.java create mode 100644 src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPeerAlgorithm.java create mode 100644 src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceDownloadAlgorithm.java create mode 100644 src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceUploadAlgorithm.java delete mode 100644 src/main/java/net/torrent/protocol/tracker/codec/ISO8859HttpRequestEncoder.java delete mode 100644 src/test/java/net/bittorrent/protocol/tracker/HttpTorrentTrackerAnnouncerTest.java create mode 100644 src/test/resources/logging.properties diff --git a/.classpath b/.classpath index ad81989..5776e5f 100644 --- a/.classpath +++ b/.classpath @@ -4,8 +4,8 @@ - - + + diff --git a/.gitignore b/.gitignore index e351214..f709ad4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /target /store.bin /target +/logging.properties diff --git a/.project b/.project index f9ad6f7..4650023 100644 --- a/.project +++ b/.project @@ -11,12 +11,13 @@ - org.maven.ide.eclipse.maven2Builder + org.eclipse.m2e.core.maven2Builder + org.eclipse.m2e.core.maven2Nature org.eclipse.jdt.core.javanature org.maven.ide.eclipse.maven2Nature diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs index 3940f5a..aba7c47 100644 --- a/.settings/org.eclipse.jdt.core.prefs +++ b/.settings/org.eclipse.jdt.core.prefs @@ -1,3 +1,6 @@ -#Thu Apr 28 01:49:42 BRT 2011 +#Wed Sep 14 13:05:56 BRT 2011 eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..a5162ba --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,5 @@ +#Wed Sep 14 13:04:25 BRT 2011 +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/pom.xml b/pom.xml index 8570a1c..1746279 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ libtorrent jar libtorrent - 1.0.0-alpha2 + 1.0.0-alpha2.1 Java library used for downloading and uploading torrent files http://code.google.com/p/libtorrent-java @@ -35,6 +35,11 @@ 3.2.4.Final compile + + org.slf4j + slf4j-api + 1.6.2 + @@ -47,12 +52,18 @@ junit 4.8.2 jar - compile + test + + + org.slf4j + slf4j-jdk14 + 1.6.2 + runtime - package + assembly @@ -68,6 +79,15 @@ + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.6 + 1.6 + org.apache.maven.plugins @@ -97,30 +117,34 @@ + + + + + + + + + + + + + + org.apache.maven.plugins - maven-pdf-plugin - 1.1 + maven-assembly-plugin + + + src/assembly/distribution-bin.xml + + - pdf + jar package - pdf - - - - - - org.apache.maven.plugins - maven-clean-plugin - 2.4.1 - - - clean - package - - clean + assembly diff --git a/src/assembly/distribution-bin.xml b/src/assembly/distribution-bin.xml new file mode 100644 index 0000000..51bbd69 --- /dev/null +++ b/src/assembly/distribution-bin.xml @@ -0,0 +1,33 @@ + + bin + + tar.gz + tar.bz2 + zip + + + + + ${project.build.directory} + / + + ${project.artifactId}-${project.version}.jar + ${project.artifactId}-${project.version}-javadoc.jar + + + + + + /libs + true + false + runtime + + net.bittorrent:libtorrent + + + + \ No newline at end of file diff --git a/src/main/java/net/torrent/BitTorrentClient.java b/src/main/java/net/torrent/BitTorrentClient.java index 7c77786..d1c3acd 100644 --- a/src/main/java/net/torrent/BitTorrentClient.java +++ b/src/main/java/net/torrent/BitTorrentClient.java @@ -15,16 +15,24 @@ */ package net.torrent; +import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; +import java.net.MalformedURLException; import java.util.Timer; import java.util.TimerTask; import net.torrent.protocol.algorithm.TorrentAlgorithm; import net.torrent.protocol.peerwire.PeerWireManager; import net.torrent.protocol.peerwire.manager.TorrentManager; +import net.torrent.protocol.tracker.HttpTorrentTrackerAnnouncer; import net.torrent.torrent.context.TorrentContext; import net.torrent.torrent.context.TorrentPeer; +import org.jboss.netty.channel.ChannelFuture; +import org.jboss.netty.channel.ChannelFutureListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * This is the main class used to controll your torrent transfer. It is not * recommended to directly instantiate this class, instead use @@ -33,6 +41,11 @@ import net.torrent.torrent.context.TorrentPeer; * @author Rogiel Josias Sulzbach */ public class BitTorrentClient implements Runnable { + /** + * The logger instance + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + /** * Configuration of an BitTorrentClient. */ @@ -100,8 +113,21 @@ public class BitTorrentClient implements Runnable { if (config.getListenPort() > 0) peerWire.listen(config.getListenPort()); + final HttpTorrentTrackerAnnouncer announcer = new HttpTorrentTrackerAnnouncer( + context.getSwarm()); + try { + announcer.announce(context.getTorrent().getTrackers().iterator() + .next()); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // run every 10 seconds - only 1 connection per turn - connectorTimer.schedule(new ConnectorTimerTask(), 0, 10 * 1000); + connectorTimer.schedule(new ConnectorTimerTask(), 0 * 1000, 2 * 1000); if (addrs != null) for (final InetSocketAddress addr : addrs) { @@ -121,8 +147,17 @@ public class BitTorrentClient implements Runnable { public void run() { TorrentPeer peer = null; while ((peer = algorithm.getPeerAlgorithm().connect()) != null) { - peerWire.connect(peer.getSocketAddress()); + log.debug("Connecting to {}", peer); + try { + if (!peerWire.connect(peer.getSocketAddress()).await() + .isSuccess()) { + peer.setAccessible(false); + } + } catch (InterruptedException e) { + } + return; } + log.debug("No new peers to connect"); } } diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdAlgorithm.java index 4738f5b..e1b4d06 100644 --- a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdAlgorithm.java +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdAlgorithm.java @@ -36,11 +36,18 @@ public class TorrentStdAlgorithm implements TorrentAlgorithm { public TorrentStdAlgorithm(final TorrentManager manager, final PieceSelector selector) { - peerAlgorithm = new TorrentStdPeerAlgorithm(manager); - interestAlgorithm = new TorrentStdInterestAlgorithm(manager, selector); - downloadAlgorithm = new TorrentStdPieceDownloadAlgorithm(manager, + final TorrentStdAlgorithmContext ctx = new TorrentStdAlgorithmContext(); + + peerAlgorithm = new TorrentStdPeerAlgorithm(manager, ctx); + interestAlgorithm = new TorrentStdInterestAlgorithm(manager, ctx, selector); + downloadAlgorithm = new TorrentStdPieceDownloadAlgorithm(manager, ctx, selector); - uploadAlgorithm = new TorrentStdPieceUploadAlgorithm(manager); + uploadAlgorithm = new TorrentStdPieceUploadAlgorithm(manager, ctx); + } + + protected class TorrentStdAlgorithmContext { + public int downloadingPieces = 0; + public int activeConnections = 0; } @Override diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdInterestAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdInterestAlgorithm.java index 1b86b46..8c5fdac 100644 --- a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdInterestAlgorithm.java +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdInterestAlgorithm.java @@ -16,23 +16,36 @@ package net.torrent.protocol.algorithm.impl; import net.torrent.protocol.algorithm.TorrentInterestAlgorithm; +import net.torrent.protocol.algorithm.impl.TorrentStdAlgorithm.TorrentStdAlgorithmContext; import net.torrent.protocol.peerwire.manager.TorrentManager; import net.torrent.torrent.context.TorrentPeer; import net.torrent.torrent.context.TorrentPeer.ChokingState; import net.torrent.torrent.context.TorrentPeer.InterestState; import net.torrent.torrent.piece.PieceSelector; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Standard torrent interest algorithm * * @author Rogiel Josias Sulzbach */ public class TorrentStdInterestAlgorithm implements TorrentInterestAlgorithm { + /** + * The logger instance + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + /** * The torrent manager */ @SuppressWarnings("unused") private final TorrentManager manager; + /** + * The algorithm context + */ + private final TorrentStdAlgorithmContext context; /** * This selector is used to find the next piece to be downloaded. Parts are @@ -49,21 +62,32 @@ public class TorrentStdInterestAlgorithm implements TorrentInterestAlgorithm { * the piece selector */ public TorrentStdInterestAlgorithm(TorrentManager manager, - PieceSelector selector) { + TorrentStdAlgorithmContext context, PieceSelector selector) { this.manager = manager; + this.context = context; this.selector = selector; } @Override public InterestState interested(TorrentPeer peer) { + log.debug("Checking interest in peer {}", peer); + if (context.downloadingPieces >= 10) { + log.debug("Already downloading 10 or more pieces, no interest in {}", peer); + return InterestState.UNINTERESTED; + } + int pieces = selector.countPieces(peer); - if (pieces >= 5) + if (pieces >= 5) { + log.debug("Peer {} has {} interesting pieces", peer, pieces); return InterestState.INTERESTED; + } + log.debug("Peer {} does not have 5 or more pieces we dont have", peer); return InterestState.INTERESTED; } @Override public ChokingState choke(TorrentPeer peer) { + log.debug("Never choke peer {}", peer); return ChokingState.UNCHOKED; } } diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPeerAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPeerAlgorithm.java index a132cd0..544f093 100644 --- a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPeerAlgorithm.java +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPeerAlgorithm.java @@ -16,6 +16,7 @@ package net.torrent.protocol.algorithm.impl; import net.torrent.protocol.algorithm.TorrentPeerAlgorithm; +import net.torrent.protocol.algorithm.impl.TorrentStdAlgorithm.TorrentStdAlgorithmContext; import net.torrent.protocol.peerwire.manager.TorrentManager; import net.torrent.torrent.context.TorrentPeer; import net.torrent.torrent.context.TorrentPeer.ChokingState; @@ -27,16 +28,23 @@ import net.torrent.torrent.context.TorrentPeer.InterestState; * @author Rogiel Josias Sulzbach */ public class TorrentStdPeerAlgorithm implements TorrentPeerAlgorithm { - @SuppressWarnings("unused") private final TorrentManager manager; + /** + * The algorithm context + */ + private final TorrentStdAlgorithmContext context; - public TorrentStdPeerAlgorithm(TorrentManager manager) { + public TorrentStdPeerAlgorithm(TorrentManager manager, + TorrentStdAlgorithmContext context) { this.manager = manager; + this.context = context; } @Override public TorrentPeer connect() { - return null; + if (context.activeConnections >= 30) + return null; + return manager.getContext().getSwarm().getRandomPeer(); } @Override diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceDownloadAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceDownloadAlgorithm.java index 138d60e..dd69362 100644 --- a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceDownloadAlgorithm.java +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceDownloadAlgorithm.java @@ -19,6 +19,7 @@ import java.util.HashSet; import java.util.Set; import net.torrent.protocol.algorithm.TorrentPieceDownloadAlgorithm; +import net.torrent.protocol.algorithm.impl.TorrentStdAlgorithm.TorrentStdAlgorithmContext; import net.torrent.protocol.peerwire.manager.TorrentManager; import net.torrent.torrent.TorrentPart; import net.torrent.torrent.TorrentPiece; @@ -39,6 +40,10 @@ public class TorrentStdPieceDownloadAlgorithm implements * The torrent manager */ private final TorrentManager manager; + /** + * The algorithm context + */ + private final TorrentStdAlgorithmContext context; /** * This selector is used to find the next piece to be downloaded. Parts are @@ -64,9 +69,10 @@ public class TorrentStdPieceDownloadAlgorithm implements * @param selector * the piece selector */ - public TorrentStdPieceDownloadAlgorithm(TorrentManager manager, + public TorrentStdPieceDownloadAlgorithm(TorrentManager manager,TorrentStdAlgorithmContext context, PieceSelector selector) { this.manager = manager; + this.context = context; this.selector = selector; } diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceUploadAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceUploadAlgorithm.java index f01a4b0..17f439f 100644 --- a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceUploadAlgorithm.java +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentStdPieceUploadAlgorithm.java @@ -16,6 +16,7 @@ package net.torrent.protocol.algorithm.impl; import net.torrent.protocol.algorithm.TorrentPieceUploadAlgorithm; +import net.torrent.protocol.algorithm.impl.TorrentStdAlgorithm.TorrentStdAlgorithmContext; import net.torrent.protocol.peerwire.manager.TorrentManager; import net.torrent.torrent.TorrentPart; import net.torrent.torrent.context.TorrentPeer; @@ -29,9 +30,15 @@ public class TorrentStdPieceUploadAlgorithm implements TorrentPieceUploadAlgorithm { @SuppressWarnings("unused") private final TorrentManager manager; + /** + * The algorithm context + */ + private final TorrentStdAlgorithmContext context; - public TorrentStdPieceUploadAlgorithm(TorrentManager manager) { + public TorrentStdPieceUploadAlgorithm(TorrentManager manager, + TorrentStdAlgorithmContext context) { this.manager = manager; + this.context = context; } @Override diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestAlgorithm.java new file mode 100644 index 0000000..0e0445b --- /dev/null +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestAlgorithm.java @@ -0,0 +1,65 @@ +/* + * Copyright 2011 Rogiel Josias Sulzbach + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.torrent.protocol.algorithm.impl; + +import net.torrent.protocol.algorithm.TorrentAlgorithm; +import net.torrent.protocol.algorithm.TorrentInterestAlgorithm; +import net.torrent.protocol.algorithm.TorrentPeerAlgorithm; +import net.torrent.protocol.algorithm.TorrentPieceDownloadAlgorithm; +import net.torrent.protocol.algorithm.TorrentPieceUploadAlgorithm; +import net.torrent.protocol.peerwire.manager.TorrentManager; +import net.torrent.torrent.piece.PieceSelector; + +/** + * Standard torrent algorithm + * + * @author Rogiel Josias Sulzbach + */ +public class TorrentTestAlgorithm implements TorrentAlgorithm { + private final TorrentPeerAlgorithm peerAlgorithm; + private final TorrentInterestAlgorithm interestAlgorithm; + private final TorrentPieceDownloadAlgorithm downloadAlgorithm; + private final TorrentPieceUploadAlgorithm uploadAlgorithm; + + public TorrentTestAlgorithm(final TorrentManager manager, + final PieceSelector selector) { + peerAlgorithm = new TorrentTestPeerAlgorithm(manager); + interestAlgorithm = new TorrentTestInterestAlgorithm(manager, selector); + downloadAlgorithm = new TorrentTestPieceDownloadAlgorithm(manager, + selector); + uploadAlgorithm = new TorrentTestPieceUploadAlgorithm(manager); + } + + @Override + public TorrentPeerAlgorithm getPeerAlgorithm() { + return peerAlgorithm; + } + + @Override + public TorrentInterestAlgorithm getInterestAlgorithm() { + return interestAlgorithm; + } + + @Override + public TorrentPieceDownloadAlgorithm getDownloadAlgorithm() { + return downloadAlgorithm; + } + + @Override + public TorrentPieceUploadAlgorithm getUploadAlgorithm() { + return uploadAlgorithm; + } +} diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestInterestAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestInterestAlgorithm.java new file mode 100644 index 0000000..ef681a2 --- /dev/null +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestInterestAlgorithm.java @@ -0,0 +1,69 @@ +/* + * Copyright 2011 Rogiel Josias Sulzbach + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.torrent.protocol.algorithm.impl; + +import net.torrent.protocol.algorithm.TorrentInterestAlgorithm; +import net.torrent.protocol.peerwire.manager.TorrentManager; +import net.torrent.torrent.context.TorrentPeer; +import net.torrent.torrent.context.TorrentPeer.ChokingState; +import net.torrent.torrent.context.TorrentPeer.InterestState; +import net.torrent.torrent.piece.PieceSelector; + +/** + * Standard torrent interest algorithm + * + * @author Rogiel Josias Sulzbach + */ +public class TorrentTestInterestAlgorithm implements TorrentInterestAlgorithm { + /** + * The torrent manager + */ + @SuppressWarnings("unused") + private final TorrentManager manager; + + /** + * This selector is used to find the next piece to be downloaded. Parts are + * managed inside this algorithm. + */ + private final PieceSelector selector; + + /** + * Creates a new instance + * + * @param manager + * the manager + * @param selector + * the piece selector + */ + public TorrentTestInterestAlgorithm(TorrentManager manager, + PieceSelector selector) { + this.manager = manager; + this.selector = selector; + } + + @Override + public InterestState interested(TorrentPeer peer) { + int pieces = selector.countPieces(peer); + if (pieces >= 5) + return InterestState.INTERESTED; + return InterestState.INTERESTED; + } + + @Override + public ChokingState choke(TorrentPeer peer) { + return ChokingState.UNCHOKED; + } +} diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPeerAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPeerAlgorithm.java new file mode 100644 index 0000000..76a589e --- /dev/null +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPeerAlgorithm.java @@ -0,0 +1,73 @@ +/* + * Copyright 2011 Rogiel Josias Sulzbach + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.torrent.protocol.algorithm.impl; + +import net.torrent.protocol.algorithm.TorrentPeerAlgorithm; +import net.torrent.protocol.peerwire.manager.TorrentManager; +import net.torrent.torrent.context.TorrentPeer; +import net.torrent.torrent.context.TorrentPeer.ChokingState; +import net.torrent.torrent.context.TorrentPeer.InterestState; + +/** + * Standard torrent peer algorithm + * + * @author Rogiel Josias Sulzbach + */ +public class TorrentTestPeerAlgorithm implements TorrentPeerAlgorithm { + @SuppressWarnings("unused") + private final TorrentManager manager; + + public TorrentTestPeerAlgorithm(TorrentManager manager) { + this.manager = manager; + } + + @Override + public TorrentPeer connect() { + return null; + } + + @Override + public PeerDiscoveredAction discovered(TorrentPeer peer) { + return PeerDiscoveredAction.CONNECT; + } + + @Override + public KeepAliveAction keepAlive(TorrentPeer peer) { + return KeepAliveAction.KEEP_ALIVE; + } + + @Override + public ChokingState interested(TorrentPeer peer, InterestState interest) { + switch (interest) { + case INTERESTED: + return ChokingState.UNCHOKED; + case UNINTERESTED: + return ChokingState.CHOKED; + } + return null; + } + + @Override + public PeerChokedAction choked(TorrentPeer peer, ChokingState state) { + switch (state) { + case CHOKED: + return PeerChokedAction.NONE; + case UNCHOKED: + return PeerChokedAction.DOWNLOAD; + } + return null; + } +} diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceDownloadAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceDownloadAlgorithm.java new file mode 100644 index 0000000..19e5b90 --- /dev/null +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceDownloadAlgorithm.java @@ -0,0 +1,118 @@ +/* + * Copyright 2011 Rogiel Josias Sulzbach + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.torrent.protocol.algorithm.impl; + +import java.util.HashSet; +import java.util.Set; + +import net.torrent.protocol.algorithm.TorrentPieceDownloadAlgorithm; +import net.torrent.protocol.peerwire.manager.TorrentManager; +import net.torrent.torrent.TorrentPart; +import net.torrent.torrent.TorrentPiece; +import net.torrent.torrent.context.TorrentPeer; +import net.torrent.torrent.piece.PieceSelector; + +/** + * This standard implementation of {@link TorrentPieceDownloadAlgorithm} chooses + * a random missing piece and tries to download all the parts from the same + * peer, following the standard behavior of most of torrent clients. + * + * @author Rogiel Josias Sulzbach + */ +// TODO separate standard algorithm from extension ones +public class TorrentTestPieceDownloadAlgorithm implements + TorrentPieceDownloadAlgorithm { + /** + * The torrent manager + */ + private final TorrentManager manager; + + /** + * This selector is used to find the next piece to be downloaded. Parts are + * managed inside this algorithm. + */ + private final PieceSelector selector; + /** + * Maps all unchecked completed pieces. The piece is removed from the list + * once + * {@link TorrentPieceDownloadAlgorithm#isComplete(TorrentPeer, TorrentPiece)} + * is called. + */ + private Set completedPieces = new HashSet(); + + /** + * Creates a new instance of this algorithm. + * + * @param manager + * the torrent manager instance. With this object is possible to + * retrieve current downloads/uploads and connections. + * @param pieceSelector + * the piece selector + * @param selector + * the piece selector + */ + public TorrentTestPieceDownloadAlgorithm(TorrentManager manager, + PieceSelector selector) { + this.manager = manager; + this.selector = selector; + } + + @Override + public TorrentPart getNextPart(TorrentPeer peer, TorrentPart part) { + if (part != null) { + if (part.isLast()) { + completedPieces.add(part.getPiece()); + } else { + return part.getNextPart(); + } + } + TorrentPiece piece = selector.select(peer); + if (piece == null) + // no piece, return null. The default handler will check, again, the + // interest on this peer. + return null; + return piece.getFirstPart(); + } + + @Override + public TorrentPart sugested(TorrentPeer peer, TorrentPiece piece) { + return piece.getFirstPart(); + } + + @Override + public TorrentPart allowedFast(TorrentPeer peer, TorrentPiece piece) { + return piece.getFirstPart(); + } + + @Override + public RejectAction rejected(TorrentPeer peer, TorrentPart part) { + return RejectAction.TRY_ANOTHER_PIECE; + } + + @Override + public boolean isComplete(TorrentPeer peer, TorrentPiece piece) { + if (manager.getContext().getBitfield().hasPiece(piece)) + return true; + // minimum overhead possible, will return true if was on list + return completedPieces.remove(piece); + } + + @Override + public CorruptedAction corrupted(TorrentPeer peer, TorrentPiece piece) { + // TODO ban peer sending many corrupted pieces + return CorruptedAction.CANCEL; + } +} diff --git a/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceUploadAlgorithm.java b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceUploadAlgorithm.java new file mode 100644 index 0000000..1e846a4 --- /dev/null +++ b/src/main/java/net/torrent/protocol/algorithm/impl/TorrentTestPieceUploadAlgorithm.java @@ -0,0 +1,47 @@ +/* + * Copyright 2011 Rogiel Josias Sulzbach + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package net.torrent.protocol.algorithm.impl; + +import net.torrent.protocol.algorithm.TorrentPieceUploadAlgorithm; +import net.torrent.protocol.peerwire.manager.TorrentManager; +import net.torrent.torrent.TorrentPart; +import net.torrent.torrent.context.TorrentPeer; + +/** + * Standard torrent upload algorithm + * + * @author Rogiel Josias Sulzbach + */ +public class TorrentTestPieceUploadAlgorithm implements + TorrentPieceUploadAlgorithm { + @SuppressWarnings("unused") + private final TorrentManager manager; + + public TorrentTestPieceUploadAlgorithm(TorrentManager manager) { + this.manager = manager; + } + + @Override + public RequestAction request(TorrentPeer peer, TorrentPart part) { + return RequestAction.NONE; + } + + @Override + public boolean cancel(TorrentPeer peer, TorrentPart part) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/src/main/java/net/torrent/protocol/peerwire/PeerWirePeer.java b/src/main/java/net/torrent/protocol/peerwire/PeerWirePeer.java index 9b1fdb9..a0474e6 100644 --- a/src/main/java/net/torrent/protocol/peerwire/PeerWirePeer.java +++ b/src/main/java/net/torrent/protocol/peerwire/PeerWirePeer.java @@ -44,6 +44,8 @@ import net.torrent.torrent.context.TorrentPeerCapabilities.TorrentPeerCapability import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelFuture; import org.jboss.netty.channel.ChannelFutureListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * An PeerWire Peer manages the {@link Channel channel} (the current peer @@ -54,6 +56,11 @@ import org.jboss.netty.channel.ChannelFutureListener; * @author Rogiel Josias Sulzbach */ public class PeerWirePeer { + /** + * The logger instance + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + /** * The active {@link Channel} */ @@ -109,11 +116,14 @@ public class PeerWirePeer { public void choke() { if (peer.getChokingState() == ChokingState.CHOKED) return; + log.debug("Chocking peer {}", this); + write(new ChokeMessage()).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { + log.debug("Chocked peer {}", this); peer.setChokingState(ChokingState.CHOKED); } } @@ -126,11 +136,14 @@ public class PeerWirePeer { public void unchoke() { if (peer.getChokingState() == ChokingState.UNCHOKED) return; + log.debug("Unchocking peer {}", this); + write(new UnchokeMessage()).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { + log.debug("Unchocked peer {}", this); peer.setChokingState(ChokingState.UNCHOKED); } } @@ -143,11 +156,14 @@ public class PeerWirePeer { public void interested() { if (peer.getInterestState() == InterestState.INTERESTED) return; + log.debug("Informing interest in peer {}", this); + write(new InterestedMessage()).addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { + log.debug("Interest informed to peer {}", this); peer.setInterestState(InterestState.INTERESTED); } } @@ -160,12 +176,15 @@ public class PeerWirePeer { public void uninterested() { if (peer.getInterestState() == InterestState.UNINTERESTED) return; + log.debug("Informing no interest to peer {}", this); + write(new NotInterestedMessage()).addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { + log.debug("No interest informed to peer {}", this); peer.setInterestState(InterestState.UNINTERESTED); } } @@ -184,6 +203,8 @@ public class PeerWirePeer { * @return the {@link ChannelFuture} for this message */ public ChannelFuture request(int index, int start, int length) { + log.debug("Requesting piece {} part {} with {} length to peer {}", + new Object[] { index, start, length, peer }); return write(new RequestMessage(index, start, length)); } @@ -201,6 +222,8 @@ public class PeerWirePeer { */ public void upload(int index, int start, int length, ByteBuffer data) { this.unchoke(); + log.debug("Sending piece {} part {} with {} length to {}, buffer: {}", + new Object[] { index, start, length, this, data }); write(new PieceMessage(index, start, length, data)); } @@ -211,6 +234,7 @@ public class PeerWirePeer { * the piece index */ public void have(int index) { + log.debug("Notifying have piece {} to peer {}", index, this); write(new HaveMessage(index)); } @@ -225,6 +249,9 @@ public class PeerWirePeer { * the length */ public void cancel(int index, int start, int length) { + log.debug( + "Cancelling piece {} reuquest, part {} with {} length from peer {}", + new Object[] { index, start, length, this }); write(new CancelMessage(index, start, length)); } @@ -232,6 +259,7 @@ public class PeerWirePeer { * Send an keep alive message */ public void keepAlive() { + log.debug("Keeping alive peer {}", this); write(new KeepAliveMessage()); } @@ -246,6 +274,7 @@ public class PeerWirePeer { * the port number */ public void port(short port) { + log.debug("Sending DHT port {} to peer {}", port, this); write(new PortMessage(port)); } @@ -256,6 +285,7 @@ public class PeerWirePeer { * Send an have none message. */ public void haveNone() { + log.debug("Sendind NO-PIECES message to peer {}", this); write(new HaveNoneMessage()); } @@ -266,6 +296,7 @@ public class PeerWirePeer { * Send an have all message. */ public void haveAll() { + log.debug("Sending HAVE-ALL message to peer {}", this); write(new HaveAllMessage()); } @@ -284,6 +315,9 @@ public class PeerWirePeer { */ public void reject(int index, int start, int length) { this.choke(); + log.debug( + "Rejecting part {}, starting at {} with {] length from peer {}", + new Object[] { index, start, length, this }); write(new RejectMessage(index, start, length)); } @@ -297,6 +331,7 @@ public class PeerWirePeer { * the piece index */ public void suggest(int index) { + log.debug("Suggesting piece {} to peer {}", index, this); write(new SuggestPieceMessage(index)); } @@ -311,6 +346,7 @@ public class PeerWirePeer { * the piece indexes */ public void allowedFast(int... indexes) { + log.debug("Allowing {} fast pieces to peer {}", indexes.length, this); write(new AllowedFastMessage(indexes)); } @@ -355,6 +391,16 @@ public class PeerWirePeer { return channel; } + /** + * @return + * @see org.jboss.netty.channel.Channel#isOpen() + */ + public boolean isConnected() { + if (channel == null) + return false; + return channel.isOpen(); + } + /** * Get the active {@link TorrentPeer} * diff --git a/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireAlgorithmHandler.java b/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireAlgorithmHandler.java index df0305c..5097aa9 100644 --- a/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireAlgorithmHandler.java +++ b/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireAlgorithmHandler.java @@ -55,6 +55,8 @@ import org.jboss.netty.channel.ExceptionEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.handler.timeout.IdleStateAwareChannelHandler; import org.jboss.netty.handler.timeout.IdleStateEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Standard handler responsible for forwarding calls to {@link TorrentAlgorithm} @@ -69,6 +71,11 @@ import org.jboss.netty.handler.timeout.IdleStateEvent; */ // TODO separate extensions handler from algorithm handler public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { + /** + * The logger instance + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + /** * The torrent manager */ @@ -223,9 +230,11 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { private void testInterest(PeerWirePeer peer) { switch (interestAlgorithm.interested(peer.getTorrentPeer())) { case INTERESTED: + log.debug("Algorithm is interested in peer {}", peer); peer.interested(); return; case UNINTERESTED: + log.debug("Algorithm is not interested in peer {}", peer); peer.uninterested(); return; } @@ -240,9 +249,11 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { private void testChoke(PeerWirePeer peer) { switch (interestAlgorithm.choke(peer.getTorrentPeer())) { case CHOKED: + log.debug("Algorithm wants to choke peer {}", peer); peer.choke(); return; case UNCHOKED: + log.debug("Algorithm wants to unchoke peer {}", peer); peer.unchoke(); return; } @@ -257,12 +268,14 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { * the new interest state */ private void peerIntrestUpdate(PeerWirePeer peer, InterestState state) { + log.debug("Peer {} has updated interest state to {}", peer, state); switch (peerAlgorithm.interested(peer.getTorrentPeer(), state)) { case CHOKED: + log.debug("Algorithm wants to choke peer {}", peer); peer.choke(); return; - case UNCHOKED: + log.debug("Algorithm wants to unchoke peer {}", peer); peer.unchoke(); return; } @@ -277,17 +290,22 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { * the choke state */ private void peerChokeUpdate(PeerWirePeer peer, ChokingState state) { + log.debug("Peer {} has updated choke state to {}", peer, state); switch (peerAlgorithm.choked(peer.getTorrentPeer(), state)) { case DISCONNECT: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); break; case CONNECT_NEW_PEER: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); + log.debug("Algorithm wants connect to a new peer"); connect(peerAlgorithm.connect()); return; case DOWNLOAD: + log.debug("Algorithm wants to download a piece from peer {}", peer); download(peer, downloadAlgorithm.getNextPart(peer.getTorrentPeer(), null)); return; @@ -305,25 +323,34 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { */ private void processRequest(PeerWirePeer peer, TorrentPart part) throws IOException { + log.debug("Peer {} has requested {}", peer, part); switch (uploadAlgorithm.request(peer.getTorrentPeer(), part)) { case DISCONNECT: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); break; case REJECT: + log.debug("Algorithm wants to reject part {} from peer {}", part, peer); if (!peer.getTorrentPeer().getCapabilities() - .supports(TorrentPeerCapability.FAST_PEERS)) + .supports(TorrentPeerCapability.FAST_PEERS)) { + log.debug("Peer {} do not support rejecting part {}, ignoring request", peer, part); return; + } peer.reject(part.getPiece().getIndex(), part.getStart(), part.getLength()); break; case CONNECT_NEW_PEER: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); + log.debug("Algorithm wants connect to a new peer"); connect(peerAlgorithm.connect()); break; case CHOKE: + log.debug("Algorithm wants to choke peer {}", peer); peer.choke(); break; case UPLOAD: + log.debug("Algorithm wants to upload part {} to peer {}", part, peer); upload(peer, part); break; } @@ -342,8 +369,11 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { */ private void processDownload(final PeerWirePeer peer, final TorrentPart part, ByteBuffer data) throws IOException { + log.debug("Received part {} from peer {}", part, peer); + final TorrentPart nextPart = downloadAlgorithm.getNextPart( peer.getTorrentPeer(), part); + log.debug("Next part from peer {} is {}", peer, nextPart); boolean complete = downloadAlgorithm.isComplete(peer.getTorrentPeer(), part.getPiece()); final ChannelFuture future = download(peer, nextPart); @@ -353,36 +383,47 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { return; if (!complete) return; + log.debug("Piece {} is complete, calculating check sum", part.getPiece()); if (datastore.checksum(part.getPiece())) { manager.getContext().getBitfield().setPiece(part.getPiece(), true); manager.getPeerManager().executeActive(new PeerWirePeerCallback() { @Override public void callback(PeerWirePeer peer) { + log.debug("Broadcasting HAVE {} message to all peers", part.getPiece()); peer.have(part.getPiece().getIndex()); } }); } else { - System.exit(0); + log.debug("Checksum for piece {} is not valid", part.getPiece()); manager.getContext().getBitfield().setPiece(part.getPiece(), false); switch (downloadAlgorithm.corrupted(peer.getTorrentPeer(), part.getPiece())) { case CHOKE: - if (future != null && !future.cancel()) + log.debug("Algorithm wants to choke peer {}", peer); + if (future != null && !future.cancel()) { + log.debug("Canceling part {} request from peer {}", nextPart, peer); peer.cancel(nextPart.getPiece().getIndex(), nextPart.getStart(), nextPart.getLength()); + } peer.choke(); break; case DISCONNECT: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); break; + case CONNECT_NEW_PEER: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); + log.debug("Algorithm wants connect to a new peer"); connect(peerAlgorithm.connect()); - break; + return; case CONTINUE: + log.debug("Algorithm wants to continue downloads from peer {}", peer); break; case CANCEL: + log.debug("Algorithms wants to cancel part {} request from peer {}", nextPart, peer); if (future != null && !future.cancel()) peer.cancel(nextPart.getPiece().getIndex(), nextPart.getStart(), nextPart.getLength()); @@ -398,15 +439,21 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { * the peer */ private void keepAlive(PeerWirePeer peer) { + log.debug("Peer {} is keeping alive", peer); switch (peerAlgorithm.keepAlive(peer.getTorrentPeer())) { case DISCONNECT: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); break; + case CONNECT_NEW_PEER: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); + log.debug("Algorithm wants connect to a new peer"); connect(peerAlgorithm.connect()); - break; + return; case KEEP_ALIVE: + log.debug("Algorithm wants to keep alive peer {}", peer); peer.keepAlive(); break; } @@ -493,23 +540,31 @@ public class PeerWireAlgorithmHandler extends IdleStateAwareChannelHandler { } private void rejected(PeerWirePeer peer, TorrentPart part) { + log.debug("Peer {} rejected part request {}", peer, part); switch (downloadAlgorithm.rejected(peer.getTorrentPeer(), part)) { case DISCONNECT: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); break; + case CONNECT_NEW_PEER: + log.debug("Algorithm wants to diconnect peer {}", peer); peer.disconnect(); + log.debug("Algorithm wants connect to a new peer"); connect(peerAlgorithm.connect()); - break; + return; case NOT_INTERESTED: + log.debug("Algorithm has no interest in peer {}", peer); peer.uninterested(); break; case RETRY: + log.debug("Algorithm wants to retry request for part {} from peer {}", part, peer); download(peer, part); break; case TRY_ANOTHER_PIECE: final TorrentPart nextPart = downloadAlgorithm.getNextPart( peer.getTorrentPeer(), part); + log.debug("Algorithm wants to try another part request {} from peer {}", nextPart, peer); download(peer, nextPart); break; } diff --git a/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerHeadHandler.java b/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerHeadHandler.java index 960c4e0..d6d5436 100644 --- a/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerHeadHandler.java +++ b/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerHeadHandler.java @@ -21,7 +21,6 @@ import net.torrent.protocol.peerwire.PeerWirePeer; import net.torrent.protocol.peerwire.manager.TorrentManager; import net.torrent.protocol.peerwire.message.HandshakeMessage; import net.torrent.torrent.context.TorrentPeer; -import net.torrent.torrent.context.TorrentPeerCapabilities.TorrentPeerCapability; import net.torrent.torrent.context.TorrentPeerID; import org.jboss.netty.channel.Channel; @@ -29,6 +28,8 @@ import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Handles pre-algoritihm handler stuff. @@ -38,6 +39,11 @@ import org.jboss.netty.channel.SimpleChannelHandler; * @author Rogiel Josias Sulzbach */ public class PeerWireManagerHeadHandler extends SimpleChannelHandler { + /** + * The logger instance + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + /** * The torrent manager */ @@ -88,14 +94,16 @@ public class PeerWireManagerHeadHandler extends SimpleChannelHandler { peer.setSocketAddress((InetSocketAddress) channel .getRemoteAddress()); peer.getCapabilities().setCapabilities(handshake.getReserved()); + + log.debug("Handshaked with peer {}", pwpeer); // TODO send bitfield - if (peer.getCapabilities().supports( - TorrentPeerCapability.FAST_PEERS)) { - pwpeer.haveAll(); - } else { - // pwpeer.bitfield(manager.getContext().getBitfield().getBits()); - } + // if (peer.getCapabilities().supports( + // TorrentPeerCapability.FAST_PEERS)) { + // //pwpeer.haveAll(); + // } else { + pwpeer.bitfield(manager.getContext().getBitfield().getBits()); + // } } super.messageReceived(ctx, e); } diff --git a/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerTailHandler.java b/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerTailHandler.java index dfa4e2d..e825e3b 100644 --- a/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerTailHandler.java +++ b/src/main/java/net/torrent/protocol/peerwire/handler/PeerWireManagerTailHandler.java @@ -30,6 +30,8 @@ import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.ChannelStateEvent; import org.jboss.netty.channel.MessageEvent; import org.jboss.netty.channel.SimpleChannelHandler; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Handles post-algorithm handler stuff. @@ -39,6 +41,11 @@ import org.jboss.netty.channel.SimpleChannelHandler; * @author Rogiel Josias Sulzbach */ public class PeerWireManagerTailHandler extends SimpleChannelHandler { + /** + * The logger instance + */ + private final Logger log = LoggerFactory.getLogger(this.getClass()); + /** * The torrent manager */ @@ -64,12 +71,18 @@ public class PeerWireManagerTailHandler extends SimpleChannelHandler { final Torrent torrent = manager.getTorrent(); final TorrentPart part = torrent.getPart(pieceMsg.getIndex(), pieceMsg.getStart(), pieceMsg.getLength()); + + log.debug("Removing {} from download queue", part); + manager.getDownloadManager().remove(part); } else if (msg instanceof RejectMessage) { final RejectMessage reject = (RejectMessage) msg; final Torrent torrent = manager.getTorrent(); final TorrentPart part = torrent.getPart(reject.getIndex(), reject.getStart(), reject.getLength()); + + log.debug("Removing {} from download queue", part); + manager.getDownloadManager().remove(part); } super.messageReceived(ctx, e); @@ -87,11 +100,15 @@ public class PeerWireManagerTailHandler extends SimpleChannelHandler { final Torrent torrent = manager.getContext().getTorrent(); final TorrentPart part = torrent.getPart(message.getIndex(), message.getStart(), message.getLength()); + + log.debug("Adding {} to upload queue", part); + manager.getUploadManager().add(part, peer.getTorrentPeer()); e.getFuture().addListener(new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { + log.debug("Removing {} from upload queue", part); manager.getUploadManager().remove(part); } }); @@ -100,6 +117,9 @@ public class PeerWireManagerTailHandler extends SimpleChannelHandler { final Torrent torrent = manager.getContext().getTorrent(); final TorrentPart part = torrent.getPart(message.getIndex(), message.getStart(), message.getLength()); + + log.debug("Adding {} to download queue", part); + manager.getDownloadManager().add(part, peer.getTorrentPeer()); } else if (msg instanceof CancelMessage) { final CancelMessage message = (CancelMessage) msg; @@ -110,6 +130,7 @@ public class PeerWireManagerTailHandler extends SimpleChannelHandler { @Override public void operationComplete(ChannelFuture future) throws Exception { + log.debug("Removing {} from download queue", part); manager.getDownloadManager().remove(part); } }); @@ -124,7 +145,9 @@ public class PeerWireManagerTailHandler extends SimpleChannelHandler { final PeerWirePeer peer = manager.getPeerManager().update( e.getChannel()); if (peer.getTorrentPeer() != null) { + log.debug("Removing all peer {} pieces from download queue", peer); manager.getDownloadManager().remove(peer.getTorrentPeer()); + log.debug("Removing all peer {} pieces from upload queue", peer); manager.getUploadManager().remove(peer.getTorrentPeer()); } super.channelDisconnected(ctx, e); @@ -137,7 +160,9 @@ public class PeerWireManagerTailHandler extends SimpleChannelHandler { final PeerWirePeer peer = manager.getPeerManager().remove( e.getChannel()); if (peer.getTorrentPeer() != null) { + log.debug("Removing all peer {} pieces from download queue", peer); manager.getDownloadManager().remove(peer.getTorrentPeer()); + log.debug("Removing all peer {} pieces from upload queue", peer); manager.getUploadManager().remove(peer.getTorrentPeer()); } super.channelClosed(ctx, e); diff --git a/src/main/java/net/torrent/protocol/peerwire/message/BitfieldMessage.java b/src/main/java/net/torrent/protocol/peerwire/message/BitfieldMessage.java index 6bbc4b0..bb74ffb 100644 --- a/src/main/java/net/torrent/protocol/peerwire/message/BitfieldMessage.java +++ b/src/main/java/net/torrent/protocol/peerwire/message/BitfieldMessage.java @@ -65,19 +65,15 @@ public class BitfieldMessage implements PeerWireWritableMessage, @Override public void read(ChannelBuffer buffer) throws IOException { - buffer.readerIndex(buffer.readerIndex() - 5); - int len = buffer.readInt() - 2; buffer.readByte(); // unk - bitfield = new BitSet(len * 8); + bitfield = new BitSet(8); int i = 0; - int read = 0; - while (read <= len) { + while (buffer.readable()) { byte b = buffer.readByte(); for (int j = 128; j > 0; j >>= 1) { bitfield.set(i++, (b & j) != 0); } - read++; } } diff --git a/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerAnnouncer.java b/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerAnnouncer.java index 90b59ab..61ef16e 100644 --- a/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerAnnouncer.java +++ b/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerAnnouncer.java @@ -25,6 +25,7 @@ import net.torrent.protocol.tracker.message.AnnounceMessage; import net.torrent.protocol.tracker.message.AnnounceMessage.Event; import net.torrent.torrent.Torrent; import net.torrent.torrent.TorrentTracker; +import net.torrent.torrent.context.TorrentSwarm; import org.jboss.netty.bootstrap.ClientBootstrap; import org.jboss.netty.channel.ChannelFuture; @@ -35,16 +36,21 @@ public class HttpTorrentTrackerAnnouncer { new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); - public HttpTorrentTrackerAnnouncer() { - client.setPipelineFactory(new HttpTorrentTrackerPipelineFactory()); + private final TorrentSwarm swarm; +private final Torrent torrent; + + public HttpTorrentTrackerAnnouncer(TorrentSwarm swarm) { + this.swarm = swarm; + this.torrent = swarm.getContext().getTorrent(); + client.setPipelineFactory(new HttpTorrentTrackerPipelineFactory(swarm)); } - public boolean announce(Torrent torrent, TorrentTracker tracker) + public boolean announce(TorrentTracker tracker) throws UnsupportedEncodingException, MalformedURLException { final AnnounceMessage announceMessage = new AnnounceMessage(tracker .getURL().toString(), torrent.getInfoHash().toByteArray(), - torrent.getInfoHash().toByteArray(), 10, 0, 0, 0, true, false, - Event.STARTED); + torrent.getInfoHash().toByteArray(), 10254, 0, 0, 0, true, + false, Event.STARTED); int port = (tracker.getURL().getPort() > 0 ? tracker.getURL().getPort() : tracker.getURL().getDefaultPort()); final ChannelFuture chFuture = client.connect(new InetSocketAddress( diff --git a/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerPipelineFactory.java b/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerPipelineFactory.java index 68875ee..86b846e 100644 --- a/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerPipelineFactory.java +++ b/src/main/java/net/torrent/protocol/tracker/HttpTorrentTrackerPipelineFactory.java @@ -16,38 +16,49 @@ package net.torrent.protocol.tracker; import static org.jboss.netty.channel.Channels.pipeline; -import net.torrent.protocol.tracker.codec.ISO8859HttpRequestEncoder; import net.torrent.protocol.tracker.codec.TorrentTrackerBDecoder; import net.torrent.protocol.tracker.codec.TorrentTrackerDecoder; import net.torrent.protocol.tracker.codec.TorrentTrackerEncoder; +import net.torrent.torrent.context.TorrentSwarm; import org.jboss.netty.channel.ChannelPipeline; import org.jboss.netty.channel.ChannelPipelineFactory; +import org.jboss.netty.handler.codec.http.HttpRequestEncoder; import org.jboss.netty.handler.codec.http.HttpResponseDecoder; import org.jboss.netty.handler.logging.LoggingHandler; import org.jboss.netty.logging.InternalLogLevel; public class HttpTorrentTrackerPipelineFactory implements ChannelPipelineFactory { + private final TorrentSwarm swarm; + + /** + * @param torrent + */ + public HttpTorrentTrackerPipelineFactory(TorrentSwarm swarm) { + this.swarm = swarm; + } + @Override public ChannelPipeline getPipeline() throws Exception { final ChannelPipeline pipeline = pipeline(); // log binary data input and object output - // pipeline.addFirst("logging", new LoggingHandler()); + pipeline.addFirst("logging-start", new LoggingHandler( + InternalLogLevel.INFO)); pipeline.addLast("tracker.encoder", new TorrentTrackerEncoder()); - pipeline.addLast("encoder", new ISO8859HttpRequestEncoder()); + pipeline.addLast("http.encoder", new HttpRequestEncoder()); pipeline.addLast("interceptor", new Interceptor()); - pipeline.addLast("decoder", new HttpResponseDecoder()); + pipeline.addLast("http.decoder", new HttpResponseDecoder()); pipeline.addLast("bdecoder", new TorrentTrackerBDecoder()); pipeline.addLast("tracker.decoder", new TorrentTrackerDecoder()); - pipeline.addLast("handler", new TrackerHandler()); + pipeline.addLast("handler", new TrackerHandler(swarm)); - pipeline.addLast("logging", new LoggingHandler(InternalLogLevel.WARN)); + pipeline.addLast("logging", new LoggingHandler(InternalLogLevel.INFO)); return pipeline; } diff --git a/src/main/java/net/torrent/protocol/tracker/TrackerHandler.java b/src/main/java/net/torrent/protocol/tracker/TrackerHandler.java index 519660c..f0a5a50 100644 --- a/src/main/java/net/torrent/protocol/tracker/TrackerHandler.java +++ b/src/main/java/net/torrent/protocol/tracker/TrackerHandler.java @@ -15,15 +15,43 @@ */ package net.torrent.protocol.tracker; +import java.net.Inet4Address; +import java.net.InetSocketAddress; + +import net.torrent.protocol.tracker.message.PeerListMessage; +import net.torrent.protocol.tracker.message.PeerListMessage.PeerInfo; +import net.torrent.torrent.context.TorrentPeer; +import net.torrent.torrent.context.TorrentPeerID; +import net.torrent.torrent.context.TorrentSwarm; + import org.jboss.netty.channel.ChannelHandlerContext; import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; +import org.jboss.netty.channel.SimpleChannelHandler; + +public class TrackerHandler extends SimpleChannelHandler { + private final TorrentSwarm swarm; + + /** + * @param torrent + */ + public TrackerHandler(TorrentSwarm swarm) { + this.swarm = swarm; + } -public class TrackerHandler extends SimpleChannelUpstreamHandler { @Override public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { - System.out.println(e.getMessage()); + if (e.getMessage() instanceof PeerListMessage) { + final PeerListMessage message = (PeerListMessage) e.getMessage(); + + for (final PeerInfo peerInfo : message.getPeerList()) { + final TorrentPeer peer = new TorrentPeer(swarm.getContext(), + TorrentPeerID.create(peerInfo.getPeerId()), + new InetSocketAddress(Inet4Address.getByName(peerInfo + .getIp()), peerInfo.getPort())); + swarm.add(peer); + } + } super.messageReceived(ctx, e); } } diff --git a/src/main/java/net/torrent/protocol/tracker/codec/ISO8859HttpRequestEncoder.java b/src/main/java/net/torrent/protocol/tracker/codec/ISO8859HttpRequestEncoder.java deleted file mode 100644 index 6170586..0000000 --- a/src/main/java/net/torrent/protocol/tracker/codec/ISO8859HttpRequestEncoder.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011 Rogiel Josias Sulzbach - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.torrent.protocol.tracker.codec; - -import org.jboss.netty.buffer.ChannelBuffer; -import org.jboss.netty.handler.codec.http.HttpMessage; -import org.jboss.netty.handler.codec.http.HttpRequest; -import org.jboss.netty.handler.codec.http.HttpRequestEncoder; - -public class ISO8859HttpRequestEncoder extends HttpRequestEncoder { - static final byte SP = 32; - static final byte CR = 13; - static final byte LF = 10; - - @Override - protected void encodeInitialLine(ChannelBuffer buf, HttpMessage message) - throws Exception { - HttpRequest request = (HttpRequest) message; - buf.writeBytes(request.getMethod().toString().getBytes()); - buf.writeByte(SP); - buf.writeBytes(request.getUri().getBytes()); - buf.writeByte(SP); - buf.writeBytes(request.getProtocolVersion().toString().getBytes()); - buf.writeByte(CR); - buf.writeByte(LF); - } -} diff --git a/src/main/java/net/torrent/protocol/tracker/codec/TorrentTrackerBDecoder.java b/src/main/java/net/torrent/protocol/tracker/codec/TorrentTrackerBDecoder.java index 0a2d7cf..4e682a7 100644 --- a/src/main/java/net/torrent/protocol/tracker/codec/TorrentTrackerBDecoder.java +++ b/src/main/java/net/torrent/protocol/tracker/codec/TorrentTrackerBDecoder.java @@ -22,18 +22,17 @@ import net.torrent.util.bencoding.BMap; import org.jboss.netty.channel.Channel; import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.handler.codec.http.HttpChunk; +import org.jboss.netty.handler.codec.http.DefaultHttpResponse; import org.jboss.netty.handler.codec.oneone.OneToOneDecoder; public class TorrentTrackerBDecoder extends OneToOneDecoder { @Override protected Object decode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception { - if (!(msg instanceof HttpChunk)) + if (!(msg instanceof DefaultHttpResponse)) return msg; - final HttpChunk message = (HttpChunk) msg; + final DefaultHttpResponse message = (DefaultHttpResponse) msg; - System.out.println(new String(message.getContent().array())); if (message.getContent().readableBytes() <= 0) return null; diff --git a/src/main/java/net/torrent/protocol/tracker/message/AnnounceMessage.java b/src/main/java/net/torrent/protocol/tracker/message/AnnounceMessage.java index 30d8aab..88883f2 100644 --- a/src/main/java/net/torrent/protocol/tracker/message/AnnounceMessage.java +++ b/src/main/java/net/torrent/protocol/tracker/message/AnnounceMessage.java @@ -57,7 +57,7 @@ public class AnnounceMessage implements TorrentTrackerRequestMessage { } private String ip; - private Integer numWant = 10; + private Integer numWant = 100; private String key = "avtbyit8"; private String trackerId; @@ -114,19 +114,20 @@ public class AnnounceMessage implements TorrentTrackerRequestMessage { add(builder, "downloaded", Long.toString(downloaded)); add(builder, "left", Long.toString(left)); - add(builder, "compact", compact); - add(builder, "no_peer_id", noPeerId); + //add(builder, "compact", compact); + //add(builder, "no_peer_id", noPeerId); if (event != Event.UPDATE) add(builder, "event", event.urlArg()); add(builder, "ip", ip); add(builder, "numwant", numWant); - add(builder, "key", key); - add(builder, "trackerid", trackerId); + //add(builder, "key", key); + //add(builder, "trackerid", trackerId); builder.setLength(builder.length() - 1);// trim last character it is an // unnecessary &. final URL url = new URL(builder.toString()); + System.out.println(builder.toString()); return new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, url.getPath() + "?" + url.getQuery()); @@ -136,25 +137,21 @@ public class AnnounceMessage implements TorrentTrackerRequestMessage { throws UnsupportedEncodingException { if (value == null) return; - builder.append(key + "=" + value).append("&"); + builder.append(key + "=" + URLEncoder.encode(value, "ISO-8859-1").replace("*", "%2a")).append("&"); } private void add(StringBuilder builder, String key, byte[] value) throws UnsupportedEncodingException { if (value == null) return; - add(builder, key, URLEncoder.encode(new String(value), "ISO-8859-1") - .replaceAll("\\+", "%20")); + add(builder, key, new String(value, "ISO-8859-1")); } private void addLowerCase(StringBuilder builder, String key, byte[] value) throws UnsupportedEncodingException { if (value == null) return; - add(builder, key, - URLEncoder - .encode(new String(value, "ISO-8859-1"), "ISO-8859-1") - .replaceAll("\\+", "%20").toLowerCase()); + add(builder, key, new String(value, "ISO-8859-1")); } private void add(StringBuilder builder, String key, Number value) diff --git a/src/main/java/net/torrent/protocol/tracker/message/PeerListMessage.java b/src/main/java/net/torrent/protocol/tracker/message/PeerListMessage.java index df524be..22f07d3 100644 --- a/src/main/java/net/torrent/protocol/tracker/message/PeerListMessage.java +++ b/src/main/java/net/torrent/protocol/tracker/message/PeerListMessage.java @@ -159,7 +159,7 @@ public class PeerListMessage implements TorrentTrackerResponseMessage { public static PeerInfo fromBMap(BMap map) throws BTypeException { return new PeerInfo((byte[]) map.get("peer id"), - map.getString("peer ip"), map.getInteger("port")); + map.getString("ip"), map.getInteger("port")); } public static PeerInfo fromRawIP(byte[] list, int i, int j) { diff --git a/src/main/java/net/torrent/torrent/Torrent.java b/src/main/java/net/torrent/torrent/Torrent.java index 4edbd3f..32e18dd 100644 --- a/src/main/java/net/torrent/torrent/Torrent.java +++ b/src/main/java/net/torrent/torrent/Torrent.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.net.URISyntaxException; +import java.net.URL; import java.security.InvalidParameterException; import java.util.Arrays; import java.util.Collections; @@ -340,8 +341,12 @@ public class Torrent { if (in == null) throw new InvalidParameterException("InputStream cannot be null"); - final BMap map = (BMap) new BEncodedInputStream(in).readElement(); - return new Torrent(map); + try { + final BMap map = (BMap) new BEncodedInputStream(in).readElement(); + return new Torrent(map); + } finally { + in.close(); + } } /** @@ -359,4 +364,19 @@ public class Torrent { throw new InvalidParameterException("File cannot be null"); return load(new FileInputStream(file)); } + + /** + * Load an torrent from an {@link File} + * + * @param url + * the {@link URL} + * @return the loaded {@link Torrent} instance + * @throws IOException + * @throws URISyntaxException + */ + public static Torrent load(URL url) throws IOException, URISyntaxException { + if (url == null) + throw new InvalidParameterException("File cannot be null"); + return load(url.openStream()); + } } diff --git a/src/main/java/net/torrent/torrent/context/TorrentPeer.java b/src/main/java/net/torrent/torrent/context/TorrentPeer.java index bbb482b..4101439 100644 --- a/src/main/java/net/torrent/torrent/context/TorrentPeer.java +++ b/src/main/java/net/torrent/torrent/context/TorrentPeer.java @@ -18,6 +18,8 @@ package net.torrent.torrent.context; import java.net.InetSocketAddress; import java.util.Date; +import net.torrent.protocol.peerwire.PeerWirePeer; + /** * Object representing a peer in the swarm. * @@ -118,6 +120,8 @@ public class TorrentPeer { */ private boolean accessible = true; + private PeerWirePeer peerWirePeer; + /** * Creates a new peer * @@ -313,6 +317,28 @@ public class TorrentPeer { this.accessible = accessible; } + + + /** + * @return the peerWirePeer + */ + public PeerWirePeer getPeerWirePeer() { + return peerWirePeer; + } + + /** + * @param peerWirePeer the peerWirePeer to set + */ + public void setPeerWirePeer(PeerWirePeer peerWirePeer) { + this.peerWirePeer = peerWirePeer; + } + + public boolean isConnected() { + if(this.peerWirePeer == null) + return false; + return true; + } + /** * Get the torrent context * diff --git a/src/main/java/net/torrent/torrent/context/TorrentSwarm.java b/src/main/java/net/torrent/torrent/context/TorrentSwarm.java index 476b09b..d5c3317 100644 --- a/src/main/java/net/torrent/torrent/context/TorrentSwarm.java +++ b/src/main/java/net/torrent/torrent/context/TorrentSwarm.java @@ -61,6 +61,17 @@ public class TorrentSwarm implements Iterable { return this.peers.add(peer); } + /** + * Add an given peers to the swarm + * + * @param peers + * the peers + * @return true if was not present in swarm + */ + public boolean add(List peers) { + return this.peers.addAll(peers); + } + /** * Removes an given peer from the swarm * @@ -131,6 +142,44 @@ public class TorrentSwarm implements Iterable { return null; } + /** + * Get an peer by its address + * + * @return an random peer + */ + public TorrentPeer getRandomPeer() { + if (peers.size() == 0) + return null; + return peers.get((int) (Math.random() * (peers.size() - 1))); + } + + /** + * Get an peer by its address + * + * @return an random peer + */ + public TorrentPeer getRandomOfflinePeer() { + List accessiblePeers = new ArrayList(); + List nonAccessiblePeers = new ArrayList(); + for (final TorrentPeer peer : peers) { + if (peer.isConnected()) { + if (peer.isAccessible()) { + accessiblePeers.add(peer); + } else { + nonAccessiblePeers.add(peer); + } + } + } + + List peerList = accessiblePeers; + + if (peerList.size() == 0) + peerList = nonAccessiblePeers; + if (peerList.size() == 0) + return null; + return peerList.get((int) (Math.random() * (peerList.size() - 1))); + } + /** * Lookup for a peer first by its id, then by address, if still not found, * creates a new entry. diff --git a/src/main/java/net/torrent/torrent/piece/ScoredPieceSelector.java b/src/main/java/net/torrent/torrent/piece/ScoredPieceSelector.java index 1de2aba..9553d44 100644 --- a/src/main/java/net/torrent/torrent/piece/ScoredPieceSelector.java +++ b/src/main/java/net/torrent/torrent/piece/ScoredPieceSelector.java @@ -65,7 +65,6 @@ public class ScoredPieceSelector extends SortedListPieceSelector { protected void sort(List pieces) { if (comparator != null) Collections.sort(pieces, comparator); - System.out.println(pieces); } @Override diff --git a/src/test/java/net/bittorrent/protocol/tracker/HttpTorrentTrackerAnnouncerTest.java b/src/test/java/net/bittorrent/protocol/tracker/HttpTorrentTrackerAnnouncerTest.java deleted file mode 100644 index e57a4a2..0000000 --- a/src/test/java/net/bittorrent/protocol/tracker/HttpTorrentTrackerAnnouncerTest.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2011 Rogiel Josias Sulzbach - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package net.bittorrent.protocol.tracker; - -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; - -import net.torrent.protocol.tracker.HttpTorrentTrackerAnnouncer; -import net.torrent.torrent.Torrent; - -import org.junit.Test; - -public class HttpTorrentTrackerAnnouncerTest { - @Test - public void testAnnounce() throws IOException, URISyntaxException, - InterruptedException { - final Torrent torrent = Torrent - .load(new File( - "src/test/resources/Tim Besamusca - Running Away EP Urban Sickness Audio USA1008.torrent")); - final HttpTorrentTrackerAnnouncer announcer = new HttpTorrentTrackerAnnouncer(); - System.out.println(announcer.announce(torrent, torrent.getTrackers() - .iterator().next())); - - //Thread.sleep(10 * 60 * 1000); - } -} diff --git a/src/test/java/net/torrent/protocol/peerwire/PeerWireManagerTest.java b/src/test/java/net/torrent/protocol/peerwire/PeerWireManagerTest.java index 37c2574..4d15f5b 100644 --- a/src/test/java/net/torrent/protocol/peerwire/PeerWireManagerTest.java +++ b/src/test/java/net/torrent/protocol/peerwire/PeerWireManagerTest.java @@ -15,27 +15,42 @@ */ package net.torrent.protocol.peerwire; -import java.io.File; import java.io.IOException; -import java.net.InetSocketAddress; import java.net.URISyntaxException; +import java.net.URL; +import java.util.logging.LogManager; import net.torrent.BitTorrentClient; import net.torrent.BitTorrentClientFactory; import net.torrent.torrent.Torrent; +import org.jboss.netty.logging.InternalLoggerFactory; +import org.jboss.netty.logging.JdkLoggerFactory; +import org.junit.Test; + public class PeerWireManagerTest { - // @Test + //@Test public void testPeerWire() throws IOException, InterruptedException, URISyntaxException { - final Torrent torrent = Torrent.load(new File( - "src/test/resources/oth.s01e13.avi.torrent")); + LogManager.getLogManager().readConfiguration( + this.getClass().getResourceAsStream("/logging.properties")); + InternalLoggerFactory.setDefaultFactory(new JdkLoggerFactory()); + + + //GET /announce?info_hash=9uKh%e8%2a%81%a47%5b%95%24%d7%84kD-%af%a7%93&peer_id=-TR2130-0kr8c2gx1d39&port=51413&uploaded=0&downloaded=0&left=124928000&numwant=0&key=c3gvpc8w&compact=1&supportcrypto=1&event=stopped HTTP/1.1\r\n + //GET /announce?info_hash=9uKh%E8%2a%81%A47%5B%95%24%D7%84kD-%AF%A7%93&peer_id=-TR2130-g4mvcv2iyehf&port=10254&uploaded=0&downloaded=0&left=0&compact=1&event=started HTTP/1.1 + + + final Torrent torrent = Torrent + .load(new URL( + "http://build.eclipse.org/technology/phoenix/torrents/indigo/eclipse-java-indigo-linux-gtk-x86_64.tar.gz.torrent")); System.out.println(torrent.getInfoHash()); final BitTorrentClient client = new BitTorrentClientFactory(torrent) .newBitTorrentClient(); - client.start(new InetSocketAddress("192.168.1.100", 25944)); + // client.start(new InetSocketAddress("192.168.1.100", 25944)); // client.start(new InetSocketAddress("192.168.1.110", 51413)); + client.start(); Thread.sleep(60 * 1000 * 30); } diff --git a/src/test/resources/logging.properties b/src/test/resources/logging.properties new file mode 100644 index 0000000..e192994 --- /dev/null +++ b/src/test/resources/logging.properties @@ -0,0 +1,3 @@ +handlers = java.util.logging.ConsoleHandler +.level=FINE +java.util.logging.ConsoleHandler.level = FINE \ No newline at end of file