005-console.pl - A quick demo of what can be accomplished in (slightly) less than 100 lines
this is still a very basic demonstration of a full
Net::BitTorrent-based client but I wanted to fit this into
100 comfortable lines.
It's certainly enough to get you started.
005-console.pl - (Sorta) Complete Net::BitTorrent client in under 100 lines
005-console.pl file.torrent or 005-console.pl [options] [file ...] Options: -t --torrent .torrent file to load -p --port TCP/UDP port opened for incoming connections -d --directory Base directory to store downloaded files --no-check Skip integrity check at start --options Advanced settings -? --help Display full documentation --version Display version information
To get client-wide progress updates, press
Ctrl+C. For more, see perldoc.
Open this .torrent file.
You may pass several -torrent parameters and load more than one .torrent torrent.
Port number opened to the world for incoming connections. This defaults to
0 and lets Net::BitTorrent bind to a random, unused port.
Relative or absolute directory used as a base directory for storage. By default, this is the current working directory.
Please see Net::BitTorrent::Torrent for related information.
If found, the files will not be checked for integrity and we assume that we have none of the data of this torrent.
Allows otherwise private settings to be changed. For example, to set the upload bandwidth limit...
005-console.pl --options _set_max_ul_rate=8192 [...]
You may pass several
This section only makes sense when you view the source.
If encryption is enabled, Net::BitTorrent::Peer relies on Math::BigInt to do all the 96bit math the MSE specification requires. This math is done for each and every encrypted connection so, using the slow, stock libraries will cause you all sorts of headaches.
Here, we prioritize using the easy-to-build Pari library. I suggest you do the same in your scripts if you leave encryption enabled.
Shoves everything Getopt::Long couldn't parse and looks like a file on the system into the list of potential .torrent files.
Prints usage info and exits if no torrents are in the aforementioned list.
Creates Net::BitTorrent object which opens on the port defined with the
-p command line parameter (falls back to
If N::B fails to create the new object, the script croaks here with an error message.
This is the function used later by the
It prints (among other things) the piece's index, the related infohash, and a rough estimate of the torrent's completion.
This function is used by the
outgoing_packet callbacks to report various block-level status updates in both directions.
This function saves resume data for every torrent loaded. For more information on resume data and how it's used, see 004-resume.pl.
If this is triggered more than once in a
3 second period, the script will exit.
Saves resume data on script exit.
Sets client-wide callbacks for
piece_hash_fail events. These in turn hand most of their data to functions described earlier.
Loops through each torrent file listed on the commandline...
Attempts to load the torrent into a new Net::BitTorrent::Torrent object. The new object stores related data in the directory defined on the command line, if the user decided to skip hash checking, the torrent's status is set to
START otherwise, it defaults to
START_AFTER_CHECK. The Resume parameter is set to
If creating the new object fails, the script skips to the next potential torrent.
Validates the new Net::BitTorrent::Torrent object object's data if the user hasn't disabled it on the command line.
Prints a quick status line which includes the torrent's path, a snippet of the infohash, and an indication of whether or not the torrent allows the use or the DHT swarm.
Sets a client-wide callback for
Note that this callback is set after the torrents are hashchecked. I've done this because this event is triggered every time Net::BitTorrent::Torrent::File attempts to open the file and fails. So, unless the files are preexisting, the script would dump screens full of useless error messages.
This nested loop is really more of a hack than useful code... it allows users to set otherwise private data in each loaded torrent. In the wrong hands, this can be dangerous, in the right hands, it's a great way to test activity in the swarm under various conditions without digging too deeply into the source. For more, see the
You'll probably not need anything that messes with
N::B's internals in your script.
Goes to work and takes a short nap between loops to save the CPU.
This script used to be installed with Net::BitTorrent as
For more examples, see the files under the
Sanko Robinson <firstname.lastname@example.org> - http://sankorobinson.com/
CPAN ID: SANKO
Copyright (C) 2008-2009 by Sanko Robinson <email@example.com>
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 http://www.perlfoundation.org/artistic_license_2_0. For clarification, see http://www.perlfoundation.org/artistic_2_0_notes.
When separated from the distribution, all POD documentation is covered by the Creative Commons Attribution-Share Alike 3.0 License. See http://creativecommons.org/licenses/by-sa/3.0/us/legalcode. For clarification, see http://creativecommons.org/licenses/by-sa/3.0/us/.
Neither this module nor the Author is affiliated with BitTorrent, Inc.