The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

AnyEvent::BitTorrent - Yet Another BitTorrent Client Module

Synopsis

    use AnyEvent::BitTorrent;
    my $client = AnyEvent::BitTorrent->new( path => 'some.torrent' );
    AE::cv->recv;

Description

This is a painfully simple BitTorrent client written on a whim that implements the absolute basics. For a full list of what's currently supported, what you will likely find in a future version, and what you'll never get from this, see the section entitled "This Module is Lame!"

Methods

The API, much like the module itself, is simple.

new( ... )

This constructor understands the following arguments:

path

This is the only required parameter. It's the path to a valid .torrent file.

basedir

This is the base directory all data will be stored in and/or read from. Multifile torrents will create another directory below this to store all files.

By default, this is the current working directory when new( ... ) is called.

port

This is the preferred port local host binds and expects incoming peers to connect to.

By default, this is a zero; the system will pick a port number randomly.

on_hash_fail

This is a subroutine called whenever a piece fails to pass hashcheck. The callback is handed the piece's index.

on_hash_pass

This is a subroutine called whenever a piece passes its hashcheck. The callback is handed the piece's index.

hashcheck( [...] )

This method expects...

...a list of integers. You could use this to check a range of pieces (a single file, for example).
    $client->hashcheck( 1 .. 5, 34 .. 56 );
...a single integer. Only that specific piece is checked.
    $client->hashcheck( 17 );
    $client->hashcheck( );

As pieces pass or fail, your on_hash_pass and on_hash_fail callbacks are triggered.

In addition to these, there are several informational methods which do not trigger or modify any activity:

infohash( )

Returns the 20-byte SHA1 hash of the value of the info key from the metadata file.

peerid( )

Returns the 20 byte string used to identify the client. Please see the spec below.

port( )

Returns the port number the client is listening on.

size( )

Returns the total size of all files described in the torrent's metadata.

Note that this value is recalculated every time you call this method. If you need it more than occasionally, it may be best to cache it yourself.

name( )

Returns the UTF-8 encoded string the metadata suggested name to save the file (or directory, in the case of multi-file torrents) under.

uploaded( )

Returns the total amount uploaded to remote peers.

downloaded( )

Returns the total amount downloaded from other peers.

left( )

Returns the approximate amount based on the pieces we still want multiplied by the size of pieces we still plan on downloading.

piece_length( )

Returns the number of bytes in each piece the file or files are split into. For the purposes of transfer, files are split into fixed-size pieces which are all the same length except for possibly the last one which may be truncated.

bitfield( )

Returns a packed binary string in ascending order (ready for vec()). Each index that the client has is set to one and the rest are set to zero.

wanted( )

Returns a packed binary string in ascending order (ready for vec()). Each index that the client has or simply does not want is set to zero and the rest are set to one.

Currently, this is just ~ $client->bitfield( ) but if your subclass has file based priorities, you could only 'want' the pieces which lie inside of the files you want.

files( )

Returns a list of hash references with the following keys:

length

Which is the size of file in bytes.

path

Which is the absolute path of the file.

peers( )

Returns the list of currently connected peers. The organization of these peers is not yet final so... don't write anything you don't expect to break before we hit v1.0.0.

Anything you find by skimming the source is likely not ready for public use and will be subject to change before v1.0.0.

This Module is Lame!

Yeah, I said it.

There are a few things a BitTorrent client must implement (to some degree) in order to interact with other clients in a modern day swarm. AnyEvent::BitTorrent is meant to meet that bare minimum but it's based on Moose or Mouse so you could always subclass it to add more advanced functionality. Hint, hint!

What is currently supported?

Basic stuff. We can make and handle piece requests. Deal with cancels, disconnect idle peers, unchoke folks. Normal... stuff. HTTP trackers are supported but do not perform according to spec yet.

What will probably be supported in the future?

DHT (which will likely be in a separate dist), fast extensions, multi-tracker extensions, IPv6 stuff, file download priorities... I'll get around to those.

Long term, UDP trackers may be supported.

For a detailed list, see the ToDo file included with this distribution.

What will likely never be supported?

We can't have nice things. Protocol encryption, uTP, endgame tricks, ...these will probably never be included in AnyEvent::BitTorrent.

What should I use instead?

If you're reading all of this with a scowl, there are many alternatives to this module, most of which are sure to be better suited for advanced users. I suggest (in no particular order):

BitFlu. It's written in Perl but you'll still need to be on a Linux, *BSD, et al. system to use it.
Net::BitTorrent ...in the future. I do not suggest using either the current stable or unstable versions found on CPAN. The next version is being worked on and will be based on Reflex.

If you're working on a Perl based client and would like me to link to it, send a bug report to the tracker listed below.

Subclassing AnyEvent::BitTorrent

TODO

If you subclass this module and change the way it functions to that which in any way proves harmful to individual peers or the swarm at large, rather than damage AnyEvent::BitTorrent's reputation, override the peerid attribute. Thanks.

PeerID Specification

AnyEvent::BitTorrent may be identified in a swarm by its peer id. As of this version, our peer id looks sorta like:

    -AB0110-XXXXXXXXXXXX

Where 0110 are the Major (01) and minor (10) version numbers and the Xs are random filler.

Bug Reports

If email is better for you, my address is mentioned below but I would rather have bugs sent through the issue tracker found at http://github.com/sanko/anyevent-bittorrent/issues.

Please check the ToDo file included with this distribution in case your bug is already known (...I probably won't file bug reports to myself).

See Also

Net::BitTorrent::Protocol - The package which does all of the wire protocol level heavy lifting.

Author

Sanko Robinson <sanko@cpan.org> - http://sankorobinson.com/

CPAN ID: SANKO

License and Legal

Copyright (C) 2011-2012 by Sanko Robinson <sanko@cpan.org>

This program is free software; you can redistribute it and/or modify it under the terms of The Artistic License 2.0. See the LICENSE file included with this distribution or notes on the Artistic License 2.0 for clarification.

When separated from the distribution, all original POD documentation is covered by the Creative Commons Attribution-Share Alike 3.0 License. See the clarification of the CCA-SA3.0.

Neither this module nor the Author is affiliated with BitTorrent, Inc.