Bt   java bittorrent done right

Release 1.9

Release 1.9 was published to Maven Central on December 14th, 2019.

Major points of this release are:

  • improving throughput and cutting down on memory usage by implementing so-called “direct” I/O and better block request pipelining
  • improving peer lookup and connectivity by figuring out which connections are duplicate and eliminating those
  • allowing to create private DHTs within non-public networks (previously all nodes had to have public Internet address)

Bug Fixes/Improvements:

  • onTorrentStarted called twice #117
  • Add new onMetadataAvailable event (fired after torrent’s metadata has been fetched)
  • Allow cookie to be missing in the LSD announce message
  • Make sure outgoing messages are never dropped
  • Continuous piece assignments (better request pipelining)
  • Direct I/O
  • Add configuration option for the number of outstanding requests
  • Add configuration option for send/receive buffer size
  • Add CLI parameter for DHT port
  • Allow bogon addresses, when using private DHT
  • Reliably eliminate duplicate peer connections and self connections

Release 1.8

Release 1.8 was published to Maven Central on June 14th, 2019.

New Features:

  • UPnP port mapping #80
  • Generate OSGi manifests
  • Add method for convenient stream-like access to torrent’s data

Bug Fixes/Improvements:

  • Outbound data silently discarded at high outgoing rates #94
  • Not possible to register consumers for a particular message type from more than one module #100
  • Support Base32-encoded info hashes in magnet links

Release 1.7

Release 1.7 was published to Maven Central on February 26th, 2018.

Changes/New Features:

  • Support for file selection (aka partial downloads)

Bug Fixes/Improvements:

  • Avoid creation of unnessary empty dirs when reading from a FileSystemStorageUnit that maps to an absent file
  • BEncoder: sort dictionary keys as raw byte sequences, not alphanumerical strings #50
  • Randomized rarest-first selector behaves like a sequential selector when peers are seeds #53
  • Empty files should not prevent successful verification of torrent’s data
  • NPE in DefaultChannelPipeline when there are unprocessed leftovers from MSE handshake #57
  • Incorrect behavior when the same peer participates in more than one torrent #67

Release 1.6

Release 1.6 was published to Maven Central on January 27th, 2018.

Official BEPs:

Bug Fixes/Improvements:

  • PeerTracker example does not work on Windows
  • Allow to selectively enable only a subset of standard extensions, like PEX and LSD
  • Re-use native memory messaging buffers between different peer connections
  • Check the allowed crypto key size and disable MSE if insufficient #24

Release 1.5

Release 1.5 was published to Maven Central on September 26th, 2017. There are several cool features in this release.

Runtime events

The new centralized mechanism for publishing/receiving events is represented by two DI services: bt.event.EventSink for publishing and bt.event.EventSource for subscriptions. Library users have an easy access to the EventSource instance via bt.runtime.BtRuntime#getEventSource().

Currently there are the following types of events:

  • when a new peer has been discovered for some torrent;
  • when a new connection with some peer has been established;
  • when a connection with some peer has been terminated;
  • when local information about some peer’s data has been updated (received BITFIELD or HAVE message);
  • when processing of some torrent has begun;
  • when processing of some torrent has finished;

Torrent processing listeners

This is mostly an internal enhancement, but it brings two useful features for library users:

1) Ability to stop torrent processing as soon as the metadata has been fetched. It can be convenient, when one is using magnet links and doesn’t want to download the actual data, but just the info dictionary. See bt.TorrentClientBuilder#afterTorrentFetched.

2) Ability to stop torrent processing as soon as the data has been downloaded. It is supposed to replace the custom listeners, that periodically perform state.getPiecesRemaining() == 0 checks and then invoke client.stop(). The new alternative is much more efficient, because it does not use a separate thread. See bt.TorrentClientBuilder#stopWhenDownloaded.

I/O selector

Leveraging OS I/O multiplexing allowed to significantly reduce the number of system calls and slightly cut down on the CPU usage in message dispatching loop.

Module extenders

This feature is borrowed from Bootique project (which I strongly recommend to anyone, who is interested in runnable Java applications). It replaces contribution methods with a clearer and more concise API for contributing custom extensions into the core. Instead of invoking individual contributions methods, downstream modules should now call bt.module.ServiceModule#extend(Binder) or bt.module.ProtocolModule#extend(Binder) and use methods in the returned builder instance, e.g.:


import bt.module.ProtocolModule;

public class MyModule implements Module {
    public void configure(Binder binder) {
            .addMessageHandler(20, ExtendedProtocol.class)
            .addExtendedMessageHandler("ut_metadata", UtMetadataMessageHandler.class);

…and more

As usual, here’s the complete list of what has been done:

Changes/New Features:

  • Introduce a unified, centralized mechanism for publishing/receiving events
  • Introduce a processing stage listener mechanism

Bug Fixes/Improvements:

  • Disallow to set client’s runtime other than via Bt factory method
  • Introduce module extenders for contributing custom extensions
  • Disable BEP-9 metadata exchange for private torrents
  • DefaultClient state fix when client is stopped PR#37
  • Announce stats to tracker on start, stop, complete
  • Use I/O selector for receiving incoming messages
  • Allow to override the number of peers to request from a tracker
  • Provide information on creation date and creator of the torrent
  • Support empty files