A work in progress implementation of the BitTorrent Specification as a method to learn Elixir. Inspired by Building a BitTorrent client from the ground up in Go.
> mix escript.build
> ./bittorrent --path ./my.torrent --output ./my_torrents/
- Parse a tracker file and use it to request peers from the tracker
- Connect to peers and handshake with them
- Record what pieces individual peers actually have
- Send requests for blocks
- Respect choke / unchoke
- Respect interested / not interested
- Save downloaded pieces to disk
- Dropped / timeout connection recovery
- Get working as a script
- Rearchitect focussing on one piece per peer
- Respond to requests for blocks (actually seed!)
- Re-announce to the tracker at a given interval
- Web UI for viewing torrent status
- Web UI for uploading a new torrent
- Assemble the pieces into an actual file
- Store pieces in ETS / DETS / Mnesia
- Listen for incoming connections
- Send have / cancel on completion of piece
Bittorrent
supervises one
Bittorrent.Client
, in charge of downloading the contents of a given .torrent file. It supervises N
Bittorrent.PeerDownloader
, who each are responsible for communications with a given peer.
Bittorrent.PeerDownloader
does all of the following forever:
- Fetching an available peer from the
Client
. - Once a peer is acquired use a
Task
to establish connection to this peer asynchronously. - Once a connection is established, fetch an available piece from the
Client
- Once a piece is acquired, use a
Task
to run the TCP socket loop between themselves and the peer, fetching blocks of the piece until is complete, and is reported back to theClient
. - (Loop back to step 3)
If available in Hex, the package can be installed
by adding bittorrent
to your list of dependencies in mix.exs
:
def deps do
[
{:bittorrent, "~> 0.1.0"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/bittorrent.