atomashpolskiy / bt Goto Github PK
View Code? Open in Web Editor NEWBitTorrent library and client with DHT, magnet links, encryption and more
Home Page: https://atomashpolskiy.github.io/bt/
License: Apache License 2.0
BitTorrent library and client with DHT, magnet links, encryption and more
Home Page: https://atomashpolskiy.github.io/bt/
License: Apache License 2.0
Code snippet here: https://gist.github.com/jehrhardt/5167854
Currently Bt just won't connect to peers if JCE unlimited strength is not installed. It would be better to automatically disable MSE negotiation and fallback to standard BitTorrent handshake (and throw an exception in CLI client if -e
flag is provided, i.e. encryption is required).
I've been looking through your code at everything related to direct connections to peers, but am having trouble piecing it together. I'm not using your library for BitTorrent per se, but am trying to look up peers in DHT by their ID and make a socket connection to them.
Ideally I'll stumble on code like the following:
CompletableFuture<PeerConnection> peerFut = runtime.getPeerconnectionById(peerID);
peerFut.get().postMessage(new Message("Hello"));
Is there any documentation or particular area of the source that you could point me to on establishing peer connections? I'd rather not re-write all of the hard work done by you and others required to punch holes in firewalls, etc.
(announce key: [[http://tracker.example/ann], [http://retracker.local/announce]])
If announce key contains two tiers and the first tier contains working tracker, then the current implementation of MultiTracker
will ignore (line # 133) the second tier. As a result, hi-speed local peers will not be discovered via http://retracker.local/announce
in the ISP's local network. And LSD can't help in this case, because multicast packets will be suppressed in the ISP's local network.
bt/bt-core/src/main/java/bt/tracker/MultiTracker.java
Lines 114 to 145 in 77315df
That use case isn't covered in http://www.bittorrent.org/beps/bep_0012.html
And is not taken into account in http://archive.is/GeZVd
PS
if (trackerTier.size() > 1
&& i != 0 // ;-)
) {
trackerTier.remove(i);
trackerTier.add(0, currentTracker);
}
Per the BitTorrent Protocol Specification
Dictionaries are encoded as a 'd' followed by a list of alternating keys and their corresponding values followed by an 'e'. For example, d3:cow3:moo4:spam4:eggse corresponds to {'cow': 'moo', 'spam': 'eggs'} and d4:spaml1:a1:bee corresponds to {'spam': ['a', 'b']}. Keys must be strings and appear in sorted order (sorted as raw strings, not alphanumerics).
Looks like it is not yet published. The version 1.0
Please publish it.
Or how can I manually make the jar file out of the project ?
Just taking up the invite to 'vote' for a new BEP to be implemented, per README.md 😄
Currently blocks are written to disk immediately in the same order that they arrive from peers (which in most cases is random). Quite obviously, this behaves poorly on storage devices with non-random access. We should implement an intermediate in-memory buffer of configurable size to hold the arriving blocks until a piece (or a number of pieces) is complete. When the piece(-s) is complete, it can be verified and written to disk. This will eliminate a big number of disk seeks, esp. if adjacent pieces are flushed to disk in one batch, and also the reads that are made during piece verification.
The API as shown now still uses the outdated java.io.File
API. Since this is a Java-8 only library, it should support the more recent java.nio
package for better client write-to-disk performances.
Per BEP-5:
A trackerless torrent dictionary does not have an "announce" key. Instead, a trackerless torrent has a "nodes" key.
But announce
key is always required now.
Hi @atomashpolskiy ,
I would be very thankful for little assistance. Not sure if I'm missing something.
I'm trying to setup simple example you provided, but it fails to start download either by using torrent file or magnet link.
It just starts and hangs at one point, no download has started. I can confirm that magnet url works with e.g. uTorrent application.
JCE has been installed and verified by checking max key sizes.
Environment
OS: Windows 10
Java: Oracle JDK 8u144 + JCE
Windows firewall = disabled (for testing purposes)
Using Bt release from 2017-08-11: 1.3.1, was also not working with 1.3 version.
Example code:
package com.github.bbijelic.torrent;
import java.io.File;
import bt.Bt;
import bt.data.Storage;
import bt.data.file.FileSystemStorage;
import bt.runtime.BtClient;
import bt.torrent.selector.SequentialSelector;
public class TorrentClient {
public static void main(String[] args) {
String magnetLink = "magnet:?xt=urn:btih:2b32e64f6cd755a9e54d60e205a9681d6670cfae";
Storage storage = new FileSystemStorage(new File("C:\\Users\\Snijele\\Desktop\\TEST"));
BtClient client = Bt.client().storage(storage).magnet(magnetLink)
.autoLoadModules().build();
// launch
client.startAsync(state -> {
if (state.getPiecesRemaining() == 0) {
client.stop();
}
}, 1000).join();
}
}
Log output:
20:35:03.443 [main] INFO bt.runtime.BtRuntimeBuilder - Auto-loading module bt.tracker.http.HttpTrackerModule with default configuration
20:35:03.448 [main] INFO bt.runtime.BtRuntimeBuilder - Auto-loading module bt.peerexchange.PeerExchangeModule with default configuration
20:35:03.916 [main] INFO bt.runtime.BtRuntimeBuilder - Auto-loading module bt.tracker.http.HttpTrackerModule with default configuration
20:35:03.916 [main] INFO bt.runtime.BtRuntimeBuilder - Auto-loading module bt.peerexchange.PeerExchangeModule with default configuration
20:35:03.948 [main] DEBUG bt.service.ClasspathApplicationService - Processing manifest file: jar:file:/C:/Users/Snijele/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/META-INF/MANIFEST.MF
20:35:03.949 [main] DEBUG bt.service.ClasspathApplicationService - Bundle-SymbolicName: ch.qos.logback.classic
20:35:03.950 [main] DEBUG bt.service.ClasspathApplicationService - Processing manifest file: jar:file:/C:/Users/Snijele/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar!/META-INF/MANIFEST.MF
20:35:03.950 [main] DEBUG bt.service.ClasspathApplicationService - Bundle-SymbolicName: ch.qos.logback.core
20:35:03.950 [main] DEBUG bt.service.ClasspathApplicationService - Processing manifest file: jar:file:/C:/Users/Snijele/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar!/META-INF/MANIFEST.MF
20:35:03.951 [main] DEBUG bt.service.ClasspathApplicationService - Bundle-SymbolicName: slf4j.api
20:35:03.951 [main] DEBUG bt.service.ClasspathApplicationService - Processing manifest file: jar:file:/C:/Users/Snijele/.m2/repository/com/github/atomashpolskiy/bt-http-tracker-client/1.3.1/bt-http-tracker-client-1.3.1.jar!/META-INF/MANIFEST.MF
20:35:03.951 [main] DEBUG bt.service.ClasspathApplicationService - Bundle-SymbolicName: null
20:35:03.951 [main] DEBUG bt.service.ClasspathApplicationService - Processing manifest file: jar:file:/C:/Users/Snijele/.m2/repository/org/apache/httpcomponents/httpclient/4.5.2/httpclient-4.5.2.jar!/META-INF/MANIFEST.MF
20:35:03.952 [main] DEBUG bt.service.ClasspathApplicationService - Bundle-SymbolicName: null
20:35:03.952 [main] DEBUG bt.service.ClasspathApplicationService - Processing manifest file: jar:file:/C:/Users/Snijele/.m2/repository/commons-codec/commons-codec/1.9/commons-codec-1.9.jar!/META-INF/MANIFEST.MF
20:35:03.953 [main] DEBUG bt.service.ClasspathApplicationService - Bundle-SymbolicName: org.apache.commons.codec
20:35:03.953 [main] DEBUG bt.service.ClasspathApplicationService - Processing manifest file: jar:file:/C:/Users/Snijele/.m2/repository/com/github/atomashpolskiy/bt-core/1.3.1/bt-core-1.3.1.jar!/META-INF/MANIFEST.MF
20:35:03.954 [main] DEBUG bt.service.ClasspathApplicationService - Bundle-SymbolicName: com.github.atomashpolskiy.bt-core
20:35:03.954 [main] DEBUG bt.service.ClasspathApplicationService - Will read version from manifest file: jar:file:/C:/Users/Snijele/.m2/repository/com/github/atomashpolskiy/bt-core/1.3.1/bt-core-1.3.1.jar!/META-INF/MANIFEST.MF
20:35:03.954 [main] DEBUG bt.service.ClasspathApplicationService - Bt version 1.3
20:35:04.063 [bt.service.executor-thread-1] DEBUG bt.processor.ChainProcessor - Processing next stage: torrent ID (2b32e64f6cd755a9e54d60e205a9681d6670cfae), stage (bt.processor.torrent.CreateSessionStage)
20:35:04.066 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiling messaging agent type: bt.peerexchange.PeerExchangePeerSourceFactory
20:35:04.067 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled producer method: produce
20:35:04.067 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled consumer method {consumedType=bt.peerexchange.PeerExchange}: consume
20:35:04.067 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled consumer method {consumedType=bt.protocol.extended.ExtendedHandshake}: consume
20:35:04.067 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled 3 consumer/producer methods
20:35:04.076 [bt.service.executor-thread-1] DEBUG bt.processor.ChainProcessor - Processing next stage: torrent ID (2b32e64f6cd755a9e54d60e205a9681d6670cfae), stage (bt.processor.magnet.FetchMetadataStage)
20:35:04.076 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiling messaging agent type: bt.torrent.messaging.MetadataConsumer
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled producer method: produce
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled consumer method {consumedType=bt.magnet.UtMetadata}: consume
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled consumer method {consumedType=bt.protocol.extended.ExtendedHandshake}: consume
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled 3 consumer/producer methods
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiling messaging agent type: bt.torrent.messaging.BitfieldCollectingConsumer
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled consumer method {consumedType=bt.protocol.Have}: consume
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled consumer method {consumedType=bt.protocol.Bitfield}: consume
20:35:04.077 [bt.service.executor-thread-1] DEBUG bt.torrent.compiler.MessagingAgentCompiler - Compiled 2 consumer/producer methods
Am I missing something?
I am a newbie coder. I was planning to implement BitTorrent protocol. It's like some magic for me. But I decided to checkout libraries first, and many of the libraries said in docs that they don't have DHT support and ones which did were messy.
But to check out the performance, I am gonna try out all of them, of course including bt. I was just wondering if you have plans to implement the BPE-5, the DHT, so that I can use it in the future. Or, if I have some confidence, I think I will look into your code and think about implementing DHT and contributing to bt, though it's not an easy task for a developer like me..
There are quite a few places where some peer-related artifacts are cached in the form of a Map with the key being the Peer object itself. These artifacts accumulate over time even for peers that the client is no longer connected to, making it a potential memory leak.
I am trying to download a torrent with private tracker. I'm getting this error on bt-cli:
Exception in thread "bt.net.pool.connection-worker-4" java.lang.IllegalStateException: Unsupported/inactive torrent requested
at bt.net.MSEHandshakeProcessor.negotiateIncoming(MSEHandshakeProcessor.java:361)
at bt.net.PeerConnectionFactory.createConnection(PeerConnectionFactory.java:73)
at bt.net.PeerConnectionFactory.createIncomingConnection(PeerConnectionFactory.java:57)
at bt.net.PeerConnectionPool.lambda$acceptIncomingConnection$63(PeerConnectionPool.java:347)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
The file bt.log has:
WARN DefaultTorrentDescriptor: Tracker URL protocol is not supported: https://..tracker../announce.php?passkey=XXXX
What could be happening?
Thanks
I used the instance code, even the magnet link is the same (I tried to use my own), but nothing happens
public static void main(String[] args) {
Config config = new Config() {
@Override
public int getNumOfHashingThreads() {
return Runtime.getRuntime().availableProcessors() * 2;
}
};
// enable bootstrapping from public routers
Module dhtModule = new DHTModule(new DHTConfig() {
@Override
public boolean shouldUseRouterBootstrap() {
return true;
}
});
// get download directory
Path targetDirectory = new File("~/Downloads").toPath();
// create file system based backend for torrent data
Storage storage = new FileSystemStorage(targetDirectory);
// create client with a private runtime
BtClient client = Bt.client()
.config(config)
.storage(storage)
.magnet("magnet:?xt=urn:btih:af0d9aa01a9ae123a73802cfa58ccaf355eb19f1")
.autoLoadModules()
.module(dhtModule)
.stopWhenDownloaded()
.build();
// launch
client.startAsync().join();
}
The conclusion showed 3 lines and it all ended
309 [main] INFO bt.runtime.BtRuntimeBuilder - Auto-loading module bt.tracker.http.HttpTrackerModule with default configuration
309 [main] INFO bt.runtime.BtRuntimeBuilder - Auto-loading module bt.peerexchange.PeerExchangeModule with default configuration
318 [main] INFO bt.runtime.BtRuntimeBuilder - Overriding auto-loaded module bt.dht.DHTModule
2482 [bt.net.pool.incoming-acceptor] INFO bt.net.PeerConnectionPool - Opening server channel for incoming connections @ /192.168.1.34:6891
What do I need to do to get it to work?
Depends on #11.
One corner case to keep in mind is when torrent data is not perfectly aligned with the size of a piece. In such case some unwanted files might be created on the disk. I wonder if these leftovers might simply be deleted as soon as the download is complete -- this is going to affect the bitfield, as some pieces will be only partially available. Currently Bt client will consider these pieces to be "missing" and will attempt to re-download them.
On behalf of @ckovorodkin
Randomized flavor of bt.torrent.selector.RarestFirstSelector
acts much like a sequential rarest-first selector, when most of the peers are seeds, and many or all pieces are equally available. The rarest-first selector would then choose pieces in a sequential fashion:
N = 10
while pieces is not an empty list
select and remove random piece with index K between 0 and N
shift all elements with index greater than K to left
E.g. in the simplest case there is one seed, and each piece has availability of 1. It's easy to see that the order of selection will always be skewed to lower indices (because the set of possible next pieces is handicapped by N first elements).
Hi,
I'm trying to seed a file which has been downloaded successfully. The tracker registers that the client has the whole file, but when I try to download the file using another client, the client says the tracker has no seeders.
But when I switch the clients, the BT client does download from the seeder.
Any ideas?
Thanks
Don't think this need further explaining :P
In-memory storage by itself might be useful in a number of scenarios:
All of this might be useful, but the real killer feature would be an optional "streaming" mode of operation. In this mode the storage would simply re-route the incoming data to a binary output stream. Of course, this mode will only make sense, when the sequential piece selector is used, and will require accumulating and re-ordering the arriving blocks under the hood.
One possible usage scenario would be to add an option for CLI client to stream the torrent data to stdout. Then this data can be piped to any other process, e.g. for large textual files it might be less, tail or grep. For video/audio it will be a media player that supports live stream decoding.
Hi, where can i download the jar file to put in my project to use your library? Thanks.
BitfieldHandler
doesn't validate received message.
A bitfield of the wrong length is considered an error. Clients should drop the connection if they receive bitfields that are not of the correct size, or if the bitfield has any of the spare bits set.
bt/bt-core/src/main/java/bt/protocol/handler/BitfieldHandler.java
Lines 45 to 58 in a37ca29
bt/bt-core/src/main/java/bt/net/ConnectionSource.java
Lines 149 to 154 in 6a17e0e
if (throwable != null || acquiredConnection == null || !acquiredConnection.isSuccess()) {
Aka magnet links. Coming in 1.3 release. There's a bunch of things left to do, but what's currently in master is already usable.
I actually tried used some code from bt-cli source code and there was no progress in download in my program.
I was confused. So I tried the actual bt-cli from terminal using it's jar and it's giving the same result - no progress in download. No increase in download speed too.
Why is this happening ?
Good day,
Not too sure what this is called but seeing as you have read the specifications for these protocols I'm sure you'll be able to tell.
May I ask if you have support for changing torrents? I'm sure there's a proper name for that. There's an app that uses torrent protocol to sync folders. I was thinking about this and I thought that maybe it changes the torrents contents and keep downloading them. Does bt support this?
I've just added the support for partial downloads in master, so it goes into 1.7 release. There are a few issues remaining to be solved and things to be done:
bt.processor.torrent.ProcessTorrentStage#doExecute
, which controls when download is considered finished). Maybe it's a CLI-specific issue (it's hard to say b/c there aren't any integration tests for partial downloads yet).bt.data.Bitfield
would be niceHello,
I'm completely new to the bittorrent protocol so I'm probably doing a million things wrong.
The trouble is I can't seem to get any response from UDP trackers. HTTP trackers however work fine.
This has been the case with other libraries that I have tried, so it is likely there is nothing wrong with the implementation. Any ideas how to solve this?
Thanks,
Raudius
bt.BtException: Failed to receive response from the tracker
at bt.tracker.udp.UdpMessageWorker.sendMessage(UdpMessageWorker.java:80)
at bt.tracker.udp.UdpMessageWorker.sendMessage(UdpMessageWorker.java:82)
at bt.tracker.udp.UdpMessageWorker.createSession(UdpMessageWorker.java:67)
at bt.tracker.udp.UdpMessageWorker.getSession(UdpMessageWorker.java:61)
at bt.tracker.udp.UdpMessageWorker.sendMessage(UdpMessageWorker.java:56)
at bt.tracker.udp.UdpTracker$1.announceEvent(UdpTracker.java:109)
at bt.tracker.udp.UdpTracker$1.start(UdpTracker.java:81)
at bt.tracker.MultiTracker$1.lambda$0(MultiTracker.java:61)
at bt.tracker.MultiTracker$1.tryForAllTrackers(MultiTracker.java:111)
at bt.tracker.MultiTracker$1.start(MultiTracker.java:61)
at bt.torrent.DefaultTorrentDescriptor.start(DefaultTorrentDescriptor.java:44)
at bt.DefaultClient.doStart(DefaultClient.java:76)
at bt.DefaultClient.startAsync(DefaultClient.java:70)
at bt.RuntimeAwareClient.startAsync(RuntimeAwareClient.java:30)
at bt.LazyClient.startAsync(LazyClient.java:39)
at com.canariapp.flixseek.torrentget.TorrentManager.addTorrent(TorrentManager.java:34)
at com.canariapp.flixseek.torrentget.TorrentManager.main(TorrentManager.java:65)
Caused by: java.util.concurrent.TimeoutException
at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
at bt.tracker.udp.UdpMessageWorker.sendMessage(UdpMessageWorker.java:75)
... 16 more
Using HTTP or FTP servers as seeds for BitTorrent downloads as described in BEP-19
Timeout used for whole piece, while it is more appropriate to use it for a small block.
Default timeout is 30 sec
. Let piece size is 4 MiB
. In that case peer, that has download speed less than 4 MiB / 30 sec = 136 KiB/sec
will be disconnected by timeout.
Normalization of file paths is performed in bt.data.file.FileSystemStorage
on a per-file basis. For malformed torrents this may lead to having duplicate files and storage units (esp. bad if the duplicate files have different size).
I'm trying to create a client app for this lib but it uses functions available only in java 8 and cannot run the app on pre android N since java 8 functions are only available for android N.
For example, if you want to force all torrent traffic through a VPN on a specific network interface.
Need to introduce a notion of torrent processing chain with clearly separated stages: metadata retrieval, torrent parsing, download, finalization. Library client will be able to register listeners that will receive the results of a particular stage. For instance, this might make it possible for the user to select specific files that should be downloaded from a multi-file torrent. Another example would be to move/rename the temporary download files (if we decide to add such option) after the download is complete.
decoders
assigned after fireDataReceived()
bt/bt-core/src/main/java/bt/net/pipeline/DefaultChannelPipeline.java
Lines 61 to 65 in a37ca29
fireDataReceived()
can use decoders
bt/bt-core/src/main/java/bt/net/pipeline/DefaultChannelPipeline.java
Lines 59 to 90 in a37ca29
I get the following exception when running with bt-dht inside JBoss modules:
Exception in thread "main" java.lang.IllegalAccessError: class bt.protocol.handler.PortMessageHandler cannot access its superclass bt.protocol.handler.UniqueMessageHandler
Although these classes are both in the same java package, they belong to different modules. Making UniqueMessageHandler public would solve this problem.
I guess that the same issue can be triggered using OSGI or Jigsaw.
From #20:
Not sure if this is expected to work, but I tried with "-i eth1" and I get "Failed to parse the acceptor's internet address". It would be convenient if it could resolve iface name -> ip address.
Currently local address is set in bt.runtime.Config#acceptorAddress
. It's used for:
Maybe we could provide a more sophisticated configuration, that would allow to specify a list of rules: internet addresses, address + network mask pairs, interface names, plus optionally the preferred address family.
Regarding the address selection algorithm, there are two possible implementations:
java.function.Predicate<InetAddress>
and use it to filter and select one appropriate address from those, that are available on the host. See DHTConfiguration in mldht and the corresponding issue for inspiration.When a torrent is created programmatically and not from a real binary source (like a .torrent file), we still need at least the info dictionary part to exchange metadata with peers. Would be convenient to have a dedicated Formatter/Serializer, that will handle translation of Torrent object into a byte array (deserialization is handled by MetadataService and uses YML schemas and object models for validation -- this logic can be externalized from MetadataService, which would instead be a factory for formatters/serializers). There's no real need for this right now, just an idea for a future enhancement.
Seams like library doesn't expect, that one peer can be connected to more than one torrent.
PeerConnectionPool
is a singleton:
Currently there are no integration tests for interaction with trackers, only unit tests. Need to investigate, what are the existing free tracker implementations, preferably written in Java and available in Maven Central, and if it would be possible to make use of any of those in ITs.
Exception in thread "main" java.lang.RuntimeException: Failed to create terminal
Need to isolate the verifier into a separate class with a re-usable interface. This will simplify adding new hashing algorithms and will allow to verify pieces that are not yet flushed to disk (see #8).
This project is participating in JDK 9 Quality Outreach program, so I encourage both users and developers to devote some time and test Bt under newest Java 9.
Recent JDK 9 builds can be downloaded here: http://jdk.java.net/9/
Please, report issues and bugs in this thread and via http://bugreport.java.com/ (in the latter case please post here a link to the submitted issue)
Use the following command to build with compiler's language level set to Java 9:
mvn clean install -Pjdk9
Per #21 it's now possible to create a FileSystemStorage with a java.nio.files.Path
. Next logical step is to leverage this new feature in ITs, more specifically in bt.it.fixture.BaseBtTest
and other related classes in bt.it.fixture
, by using an in-memory storage, that supports java.nio.files
API, e.g Jimfs, which was mentioned in #21.
Yesterday I've started working on adding support for MSE [1], which, as far as I know, is the most common implementation of the BitTorrent protocol encryption (obfuscation), used to circumvent traffic blocking/shaping by ISPs.
WIP is available in a dedicated branch.
I'm working the Bt a few weeks , but i have been stumped how to use the infohash to get connection with peer and download torrent file T_T . when i send a query to ask for more piece , the peer is not response for that , but other request is response correct such as handshake .
Could you show me how to do this?
Thank you .
It looks like since you added event listener to the event bus, you can't remove it. It would be nice to have such ability to remove listeners by reference or by some id.
From time to time peerBitfields.put(peer, bitfield);
replaces previous value and drop out it without updating pieceTotals[]
bt/bt-core/src/main/java/bt/torrent/BitfieldBasedStatistics.java
Lines 56 to 65 in a37ca29
BitfieldBasedStatistics
.A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.