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