1
0
mirror of https://github.com/Rogiel/torrent4j synced 2025-12-05 23:22:49 +00:00

Implements peer's client matching using PeerID

This commit is contained in:
2012-04-07 00:44:13 -03:00
parent 2ff24d80af
commit b3e6b47cb6
10 changed files with 211 additions and 20 deletions

21
pom.xml
View File

@@ -94,6 +94,7 @@
<descriptors> <descriptors>
<descriptor>src/main/assembly/distribution-bin.xml</descriptor> <descriptor>src/main/assembly/distribution-bin.xml</descriptor>
</descriptors> </descriptors>
<attach>false</attach>
</configuration> </configuration>
</plugin> </plugin>
@@ -130,6 +131,10 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId> <artifactId>maven-release-plugin</artifactId>
<version>2.2.2</version> <version>2.2.2</version>
<configuration>
<autoVersionSubmodules>true</autoVersionSubmodules>
<goals>deploy site-deploy</goals><!-- we have to force site-deploy -->
</configuration>
</plugin> </plugin>
<plugin> <plugin>
@@ -183,7 +188,7 @@
<artifactId>site-maven-plugin</artifactId> <artifactId>site-maven-plugin</artifactId>
<version>0.4</version> <version>0.4</version>
<configuration> <configuration>
<message>Creating site for ${project.version}</message> <message>Creating ${project.artifactId} site for ${project.version}</message>
<repositoryOwner>torrent4j</repositoryOwner> <repositoryOwner>torrent4j</repositoryOwner>
<repositoryName>torrent4j.github.com</repositoryName> <repositoryName>torrent4j.github.com</repositoryName>
</configuration> </configuration>
@@ -203,6 +208,9 @@
<configuration> <configuration>
<repositoryOwner>torrent4j</repositoryOwner> <repositoryOwner>torrent4j</repositoryOwner>
<repositoryName>torrent4j</repositoryName> <repositoryName>torrent4j</repositoryName>
<includes>
<include>${project.build.directory}/${project.artifactId}-${project.version}.zip</include>
</includes>
</configuration> </configuration>
<executions> <executions>
<execution> <execution>
@@ -264,6 +272,17 @@
<artifactId>commons-codec</artifactId> <artifactId>commons-codec</artifactId>
<version>20041127.091804</version> <version>20041127.091804</version>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.6.2</version>
<scope>runtime</scope>
</dependency>
</dependencies> </dependencies>

View File

@@ -21,7 +21,7 @@ public class TestMain {
new PeerWireProtocol(), new InMemoryTorrentStorage()); new PeerWireProtocol(), new InMemoryTorrentStorage());
controller.start(1234); controller.start(1234);
final Torrent torrent = Torrent.load(Paths.get("music.torrent")); final Torrent torrent = Torrent.load(Paths.get("test.torrent"));
System.out.println("Torrent hash is " + torrent.getHash().getString()); System.out.println("Torrent hash is " + torrent.getHash().getString());
// controller.checkExistingData(torrent); // controller.checkExistingData(torrent);
@@ -29,7 +29,7 @@ public class TestMain {
controller.registerTorrent(torrent); controller.registerTorrent(torrent);
final TorrentPeer peer = new TorrentPeer(torrent); final TorrentPeer peer = new TorrentPeer(torrent);
peer.setAddress(new InetSocketAddress(Inet4Address peer.setAddress(new InetSocketAddress(Inet4Address
.getByName("192.168.1.100"), 21958)); .getByName("127.0.0.1"), 34096));
torrent.getSwarm().addPeer(peer); torrent.getSwarm().addPeer(peer);
while(true) { while(true) {

View File

@@ -27,7 +27,7 @@ public class TorrentPeer {
/** /**
* The peer ID * The peer ID
*/ */
private String peerID; private TorrentPeerID peerID;
/** /**
* The protocol peer used to communicate with it * The protocol peer used to communicate with it
@@ -67,13 +67,27 @@ public class TorrentPeer {
return pieces; return pieces;
} }
public String getPeerID() { public TorrentPeerID getPeerID() {
return peerID; return peerID;
} }
public void setPeerID(String peerID) { public void setPeerID(TorrentPeerID peerID) {
this.peerID = peerID; this.peerID = peerID;
} }
public void setPeerID(String peerID) {
this.peerID = new TorrentPeerID(this, peerID);
}
/**
* Tries to detect the peer's client. If unknown, {@link TorrentPeerClient#UNKNOWN} is
* returned.
*
* @return the peer torrent client
*/
public TorrentPeerClient getClient() {
return peerID.getClient();
}
public TorrentProtocolPeer getProtocolPeer() { public TorrentProtocolPeer getProtocolPeer() {
return protocolPeer; return protocolPeer;

View File

@@ -0,0 +1,45 @@
package com.torrent4j.model;
/**
* The list of known torrent clients
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public enum TorrentPeerClient {
/**
* µTorrent for Mac (<strong>-UM</strong>)
*/
UTORRENT_FOR_MAC("µTorrent for Mac", "-UM"),
/**
* µTorrent (<strong>-UT</strong>)
*/
UTORRENT("µTorrent", "-UT"),
/**
* Transmission (<strong>-TR</strong>)
*/
TRANSMISSION("Transmission", "-TR"),
UNKNOWN("Unknown", "");
/**
* An friendly name for the client. Can be used on an UI.
*/
public final String friendlyName;
/**
* The PeerID prefix for the client
*/
public final String prefix;
/**
* Initializes a new enum value
*
* @param friendlyName
* an friendly name for the client
* @param prefix
* the PeerID prefix
*/
private TorrentPeerClient(String friendlyName, String prefix) {
this.friendlyName = friendlyName;
this.prefix = prefix;
}
}

View File

@@ -0,0 +1,67 @@
package com.torrent4j.model;
/**
* This ID represents an PeerID on the BitTorrent network
*
* @author <a href="http://www.rogiel.com">Rogiel</a>
*/
public class TorrentPeerID {
/**
* The torrent peer
*/
private final TorrentPeer peer;
/**
* The underlying peer ID
*/
private final String peerID;
/**
* Creates a new instance
*
* @param peer
* the peer
* @param peerID
* the peer ID
*/
public TorrentPeerID(TorrentPeer peer, String peerID) {
this.peer = peer;
this.peerID = peerID;
}
/**
* @return the peerID
*/
public String getPeerID() {
return peerID;
}
/**
* Tries to detect the peer's client. If unknown, {@link TorrentPeerClient#UNKNOWN} is
* returned.
*
* @return the peer torrent client
*/
public TorrentPeerClient getClient() {
for(TorrentPeerClient client : TorrentPeerClient.values()) {
if(client == TorrentPeerClient.UNKNOWN)
continue;
if(peerID.startsWith(client.prefix))
return client;
}
return TorrentPeerClient.UNKNOWN;
}
/**
* @return the peer
*/
public TorrentPeer getPeer() {
return peer;
}
/**
* @return the torrent
*/
public Torrent getTorrent() {
return peer.getTorrent();
}
}

View File

@@ -71,14 +71,15 @@ public class PeerWireHandler extends SimpleChannelHandler {
message.peerID); message.peerID);
if (peer == null) { if (peer == null) {
peer = new TorrentPeer(torrent); peer = new TorrentPeer(torrent);
peer.setPeerID(message.peerID);
peer.setAddress((InetSocketAddress) e.getChannel() peer.setAddress((InetSocketAddress) e.getChannel()
.getRemoteAddress()); .getRemoteAddress());
} }
peer.setPeerID(message.peerID);
this.peer = (PeerWireProtocolPeer) peer.getProtocolPeer(); this.peer = (PeerWireProtocolPeer) peer.getProtocolPeer();
e.getChannel().getPipeline().get(PeerTrafficShapingHandler.class) e.getChannel().getPipeline()
.setPeer(peer); .get(PeerTrafficShapingHandler.class).setPeer(peer);
e.getChannel().getPipeline() e.getChannel().getPipeline()
.get(TorrentTrafficShapingHandler.class) .get(TorrentTrafficShapingHandler.class)
.setTorrent(torrent); .setTorrent(torrent);
@@ -87,6 +88,11 @@ public class PeerWireHandler extends SimpleChannelHandler {
this.peer.getStrategy().getPeerStrategy() this.peer.getStrategy().getPeerStrategy()
.peerConnected(torrent, peer); .peerConnected(torrent, peer);
} else if (msg instanceof HaveMessage) { } else if (msg instanceof HaveMessage) {
peer.getTorrentPeer()
.getPieces()
.addPiece(
peer.getTorrent().getPiece(
((HaveMessage) msg).pieceIndex));
peer.getStrategy() peer.getStrategy()
.getPeerStrategy() .getPeerStrategy()
.havePiece( .havePiece(
@@ -127,6 +133,11 @@ public class PeerWireHandler extends SimpleChannelHandler {
message.pieceIndex); message.pieceIndex);
final TorrentPieceBlock block = piece.getBlock(message.begin, final TorrentPieceBlock block = piece.getBlock(message.begin,
message.length); message.length);
if(peer.getTorrentPeer().getState().hasUploadRequestedBlock()) {
peer.disconnect();
return;
}
peer.getTorrentPeer().getState().setUploadRequestedBlock(block); peer.getTorrentPeer().getState().setUploadRequestedBlock(block);
peer.getTorrentPeer().getState() peer.getTorrentPeer().getState()
@@ -233,8 +244,19 @@ public class PeerWireHandler extends SimpleChannelHandler {
peer.getTorrentPeer().getState().setLastUploadedBlock(block); peer.getTorrentPeer().getState().setLastUploadedBlock(block);
peer.getTorrentPeer().getState() peer.getTorrentPeer().getState()
.setLastUploadedBlockDate(new Date()); .setLastUploadedBlockDate(new Date());
peer.getTorrentPeer().getState().setUploadRequestedBlock(null);
peer.getTorrentPeer().getState().setUploadRequestedDate(null); e.getFuture().addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
throws Exception {
if (!future.isSuccess())
return;
peer.getTorrentPeer().getState()
.setUploadRequestedBlock(null);
peer.getTorrentPeer().getState()
.setUploadRequestedDate(null);
}
});
} else if (msg instanceof RequestMessage) { } else if (msg instanceof RequestMessage) {
final RequestMessage message = (RequestMessage) msg; final RequestMessage message = (RequestMessage) msg;
@@ -248,9 +270,18 @@ public class PeerWireHandler extends SimpleChannelHandler {
peer.getTorrentPeer().getState() peer.getTorrentPeer().getState()
.setDownloadRequestedDate(new Date()); .setDownloadRequestedDate(new Date());
} else if (msg instanceof CancelMessage) { } else if (msg instanceof CancelMessage) {
peer.getTorrentPeer().getState() e.getFuture().addListener(new ChannelFutureListener() {
.setDownloadRequestedBlock(null); @Override
peer.getTorrentPeer().getState().setDownloadRequestedDate(null); public void operationComplete(ChannelFuture future)
throws Exception {
if (!future.isSuccess())
return;
peer.getTorrentPeer().getState()
.setDownloadRequestedBlock(null);
peer.getTorrentPeer().getState()
.setDownloadRequestedDate(null);
}
});
} }
} finally { } finally {
ctx.sendDownstream(e); ctx.sendDownstream(e);

View File

@@ -3,6 +3,8 @@ package com.torrent4j.net.peerwire;
import static io.netty.channel.Channels.pipeline; import static io.netty.channel.Channels.pipeline;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.ChannelPipelineFactory; import io.netty.channel.ChannelPipelineFactory;
import io.netty.handler.logging.LoggingHandler;
import io.netty.logging.InternalLogLevel;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -11,8 +13,8 @@ import com.torrent4j.net.peerwire.codec.PeerWireFrameDecoder;
import com.torrent4j.net.peerwire.codec.PeerWireFrameEncoder; import com.torrent4j.net.peerwire.codec.PeerWireFrameEncoder;
import com.torrent4j.net.peerwire.codec.PeerWireMessageDecoder; import com.torrent4j.net.peerwire.codec.PeerWireMessageDecoder;
import com.torrent4j.net.peerwire.codec.PeerWireMessageEncoder; import com.torrent4j.net.peerwire.codec.PeerWireMessageEncoder;
import com.torrent4j.net.peerwire.traffic.TorrentTrafficShapingHandler;
import com.torrent4j.net.peerwire.traffic.PeerTrafficShapingHandler; import com.torrent4j.net.peerwire.traffic.PeerTrafficShapingHandler;
import com.torrent4j.net.peerwire.traffic.TorrentTrafficShapingHandler;
public class PeerWirePipelineFactory implements ChannelPipelineFactory { public class PeerWirePipelineFactory implements ChannelPipelineFactory {
private final TorrentController controller; private final TorrentController controller;
@@ -37,7 +39,7 @@ public class PeerWirePipelineFactory implements ChannelPipelineFactory {
p.addLast("message-decoder", new PeerWireMessageDecoder()); p.addLast("message-decoder", new PeerWireMessageDecoder());
p.addLast("message-encoder", new PeerWireMessageEncoder()); p.addLast("message-encoder", new PeerWireMessageEncoder());
// p.addLast("logging", new LoggingHandler(InternalLogLevel.WARN)); p.addLast("logging", new LoggingHandler(InternalLogLevel.WARN));
p.addLast("handler", new PeerWireHandler(controller)); p.addLast("handler", new PeerWireHandler(controller));

View File

@@ -2,6 +2,7 @@ package com.torrent4j.net.peerwire.messages;
import io.netty.buffer.ChannelBuffer; import io.netty.buffer.ChannelBuffer;
import java.nio.charset.Charset;
import java.util.Arrays; import java.util.Arrays;
import com.torrent4j.net.peerwire.PeerWireMessage; import com.torrent4j.net.peerwire.PeerWireMessage;
@@ -36,7 +37,7 @@ public class HandshakeMessage implements PeerWireMessage {
protocolString = buffer.readBytes(protocolStringLength).toString(); protocolString = buffer.readBytes(protocolStringLength).toString();
reserved = buffer.readLong(); reserved = buffer.readLong();
torrentHash = buffer.readBytes(20).array(); torrentHash = buffer.readBytes(20).array();
peerID = buffer.readBytes(20).toString(); peerID = buffer.readBytes(20).toString(Charset.forName("UTF-8"));
} }
/* /*

View File

@@ -42,9 +42,11 @@ public class StandardTorrentPeerStrategy implements TorrentPeerStrategy {
return; return;
if (peer.getState().hasDownloadRequestedBlock()) if (peer.getState().hasDownloadRequestedBlock())
return; return;
if (peer.getState().isRemotellyChoked()) if (peer.getState().isRemotellyChoked()) {
return; peer.declareInterest();
peer.requestBlock(piece.getFirstBlock()); } else {
peer.requestBlock(piece.getFirstBlock());
}
} }
@Override @Override

10
src/site/site.xml Executable file
View File

@@ -0,0 +1,10 @@
<project xmlns="http://maven.apache.org/DECORATION/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd">
<body>
<menu ref="parent" inherit="top" />
<menu ref="modules" inherit="bottom" />
<menu ref="reports" inherit="bottom" />
</body>
</project>