Download as pdf or txt
Download as pdf or txt
You are on page 1of 37

BitTorrent-Client

By

Sidharth-Shyamsukha-17BIT109
Yash-Maheshwari-17BIT126

DEPARTMENT-OF-COMPUTER-SCIENCE-&-ENGINEERING
Ahmedabad-382481
BitTorrent-Client

Mini-Project-–-III

Submitted-in-partial-fulfillment-of-the-requirements

For-the-degree-of-

Bachelor-of-Technology-in-Information-Technology-

By
Sidharth-Shyamsukha-17BIT109
Yash-Maheshwari-17BIT126

Guided-By
Dr.-Gaurang-Raval
[DEPARTMENT-OF-COMPUTER-SCIENCE-&-ENGINEERING]
DEPARTMENT-OF-COMPUTER-SCIENCE-&-ENGINEERING
Ahmedabad-382481

CERTIFICATE

This-is-to-certify-that-the-Mini-Project--III-entitled-“BitTorrent-
Client”-submitted-by-Sidharth-Shyamsukha(17BIT109)-and-Yash-
Maheshwari(17BIT126),-towards-the-partial-fulfillment-of-the-
requirements-for-the-degree-of-Bachelor-of-Technology-in-Information-
Technology/Computer-Engineering-of-Nirma-University-is-the-record-of-
work-carried-out-by-him/her-under-my-supervision-and-guidance.-In-my-
opinion,-the-submitted-work-has-reached-a-level-required-for-being-
accepted-for-examination.-

Dr.-Gaurang-Raval-----------------------------------Dr.-Madhuri-Bhavsar-
(HOD)---------
Department-of-Computer-Science-&-Engg.--------------Dept.-of-Computer-
Science-
Institute-of-Technology,----------------------------&-Engineering---
Nirma-University,-----------------------------------Institute-of-
Technology-------------------------
Ahmedabad--------------------------- ----Nirma-University
----------------------------------------------------Ahmedabad
----------------------------------------------
----------------------------------------------------------------------
-------------------
----------------------------------------------------------------------
--------------------
ACKNOWLEDGEMENT

We-wish-to-acknowledge-our-guide,-who-has-
been-totally-supportive
throughout-the-whole-project-and-helping-
us-channel-our-resources-into
better-paths.-Because-of-his-kind-and-
helpful-supervision-our-tasks
become-a-whole-lot-easier.-Finally,-we-
would-like-to-give-special-thanks-to
our-friends-and-family-for-their-kind-
support-and-never-letting-us-give-up.
Without-their-support-this-project-would-
not-be-possible.
Abstract

BitTorrent-is-a-peer-to-peer-protocol,-where-
peers-join-a-swarm-of-other-peers-to-exchange-
pieces-of-data-between-each-other.-Each-peer-is-
connected-to-multiple-peers-at-the-same-time,-
and-thus-downloading-or-uploading-to-multiple-
peers-at-the-same-time.-This-is-great-in-terms-
of-limiting-bandwidth-compared-to-when-a-file-
is-downloaded-from-a-central-server.-It-is-also-
great-for-keeping-a-file-available-as-it-does-
not-rely-on-a-single-source-being-online.

It-identifies-content-by-URL-and-is-designed-to-
integrate-seamlessly-with-the-web.-Its-
advantage-over-plain-HTTP-is-that-when-multiple-
downloads-of-the-same-file-happen-concurrently,-
the-downloaders-upload-to-each-other,-making-it-
possible-for-the-file-source-to-support-very-
large-numbers-of-downloaders-with-only-a-modest-
increase-in-its-load.
TABLE-OF-CONTENTS

Certificate
Acknowledgement
Abstract
Table-of-Contents

Topics:

1. Basics-of-Torrenting
2. Parsing-a-.torrent-file
a. Bencoding
b. Piece-size
3. Tracker
a. Tracker-File-Structure
b. Async-http
c. The-loop
4. The-Peer-Protocol
a. The-Handshake
b. Requesting-Pieces
c. The-Implementation-
5. Managing-the-pieces
a. Implementation
6. Bibliography
1. Basics-of-Torrent-Client

A-BitTorrent-client-is-an-executable-program-
which-implements-the-BitTorrent-protocol.-It-
runs-together-with-the-operating-system-on-a-
users-machine,-and-handles-interactions-with-
the-tracker-and-peers.-The-client-sits-on-the-
operating-system-and-is-responsible-for-
controlling-the-reading/writing-of-files,-
opening-sockets-etc.

The-BitTorrent-protocol-can-be-split-into-the-
following-five-main-components:

● Metainfo-File-–-a-file-which-contains-all-
details-necessary-for-the-protocol-to-
operate.
● Tracker-–-A-server-which-helps-manage-the-
BitTorrent-protocol.
● Peers-–-Users-exchanging-data-via-the-
BitTorrent-protocol.
● Data-–-The-files-being-transferred-across-
the-protocol.
● Client-–-The-program-which-sits-on-a-peers-
computer-and-implements-the-protocol.

Peers-use-TCP-(Transport-Control-Protocol)-to-
communicate-and-send-data.-This-protocol-is-
preferable-over-other-protocols-such-as-UDP-
(User-Datagram-Protocol)-because-TCP-guarantees-
reliable-and-in-order-delivery-of-data-from-
sender-to-receiver.-

UDP-can-not-give-such-guarantees,-and-data-can-
become-scrambled,-or-lost-all-together.-The-
tracker-allows-peers-to-query-which-peers-have-
what-data,-and-allows-them-to-begin-
communication.-Peers-communicate-with-the-
tracker-via-the-plain-text-via-HTTP-(Hypertext-
Transfer-Protocol)-.
2. Parsing-a-.torrent-file

BitTorrent-is-very-versatile,-and-can-be-used-
to-transfer-a-single-file,-of-multiple-files-of-
any-type,-contained-within-any-number-of-
directories.-File-sizes-can-vary-hugely,-from-
kilobytes-to-hundreds-of-gigabytes.

Data-is-split-into-smaller-pieces-which-are-
sent-between-peers-using-the-bittorrent-
protocol.-These-pieces-are-of-a-fixed-size,-
which-enables-the-tracker-to-keep-tabs-on-who-
has-which-pieces-of-data.-This-also-breaks-the-
file-into-verifiable-pieces,-each-piece-can-
then-be-assigned-a-hash-code,-which-can-be-
checked-by-the-downloader-for-data-integrity.-
These-hashes-are-stored-as-part-of-the-meta-
info-file-or-a-.torrent-file.

Every-metainfo-file-must-contain-the-following-
information,-(or-‘keys’):

● info:-A-dictionary-which-describes-the-
file(s)-of-the-torrent.-Either-for-the-
single-file,-or-the-directory-structure-for
● more-files.-Hashes-for-every-data-piece,-in-
SHA-1-format-are-stored-here.
● announce:-The-announce-URL-of-the-tracker-
as-a-string

The-following-are-optional-keys-which-can-also-
be-used:
● announce-list:-Used-to-list-backup-trackers
● creation-date:-The-creation-time-of-the-
torrent-by-way-of-UNIX-timestamp-(integer-
seconds-since-1-Jan-1970-00:00:00-UTC)
● comment:-Any-comments-by-the-author
● created-by:-Name-and-Version-of-programme-
used-to-create-the-metainfo-file

All-these-properties-are-stored-in-a-binary-
format-called-Bencoding.-It-supports-four-
different-data-types,-dictionaries,-lists,-
integers-and-strings---it-is-fairly-easy-to-
translate-to-Python’s-object-literals-or-JSON.

Because-all-information-which-is-needed-for-the-
torrent-is-included-in-a-single-file,-this-file-
can-easily-be-distributed-via-other-protocols,-
and-as-the-file-is-replicated,-the-number-of-
peers-can-increase-very-quickly.-The-most-
popular-method-of-distribution-is-using-a-
public-indexing-site-which-hosts-the-metainfo-
files.-A-seed-will-upload-the-file,-and-then-
others-can-download-a-copy-of-the-file-over-the-
HTTP-protocol-and-participate-in-the-torrent.
>>>-with-open('tests/data/ubuntu-16.04-desktop-
amd64.iso.torrent',-'rb')-as-f:
...-----meta_info-=-f.read()
...-----torrent-=-Decoder(meta_info).decode()
...
>>>-torrent
OrderedDict([(b'announce',b'http://torrent.ubuntu.com:6969/announce')
,-(b'announce-list',-[[b'http://torrent.ubuntu.com:6969/announce'],-
[b'http://ipv6.torrent.ubuntu.com:6969/announce']
]),-(b'comment',-b'Ubuntu-CD-releases.ubuntu.com'),-(b'creation-
date',-1461232732),-(b'info',-OrderedDict([(b'length',-1485881344),-
(b'name',-b'ubuntu-16.04-desktop-amd64.iso'),-(b'piece
length',-524288),-(b'pieces',-b'\x1at\xfc\x84\xc8\xfaV\xeb\x12\x1c\
xc5\xa4\x1c?\xf0\x96\x07P\x87\xb8\xb2\xa5G1\xc8L\x18\x81\x9bc\x81\
xfc8*\x9d\xf4k\xe6\xdb6\xa3\x0b\x8d\xbe\xe3L\xfd\xfd4\...')]))])

3. Tracker

A-tracker-is-used-to-manage-users-participating-
in-a-torrent-(known-as-peers).-It-stores-
statistics-about-the-torrent,-but-its-main-role-
is-to-allow-peers-to-‘find-each-other’-and-
start-communication,-i.e.-to-find-peers-with-
the-data-they-require.-Peers-know-nothing-of-
each-other-until-a-response-is-received-from-
the-tracker.-Whenever-a-peer-contacts-the-
tracker,-it-reports-which-pieces-of-a-file-they-
have.-That-way,-when-another-peer-queries-the-
tracker,-it-can-provide-a-random-list-of-peers-
who-are-participating-in-the-torrent,-and-have-
the-required-piece.

A -

tracker-is-a-HTTP/HTTPS-service-and-typically-
works-on-port-6969.-The-address-of-the-tracker-
managing-a-torrent-is-specified-in-the-metainfo-
file,-a-single-tracker-can-manage-multiple-
torrents.-Multiple-trackers-can-also-be-
specified,-as-backups,-which-are-handled-by-the-
BitTorrent-client-running-on-the-users-
computer.-
BitTorrent-clients-communicate-with-the-tracker-
using-HTTP-GET-requests,-which-is-a-standard-
CGI-method.-This-consists-of-appending-a-“?”-to-
the-URL,-and-separating-parameters-with-a-“&”.-

For-example:
https://tracker.com/announce.php?
var1=value&var2=value

The-parameters-accepted-by-the-tracker-are:

● info_hash:-20-byte-SHA1-hash-of-the-info-
key-from-the-metainfo-file.
● peer_id:-20-byte-string-used-as-a-unique-ID-
for-the-client.
● port:-The-port-number-the-client-is-listed-
on.
● uploaded:-The-total-amount-uploaded-since-
the-client-sent-the-‘started’-event-to-the-
tracker-in-base-ten-ASCII.
● downloaded:-The-total-amount-downloaded-
since-the-client-sent-the-‘started’-event-
to-the-tracker-in-base-ten-ASCII.
● left:-The-number-of-bytes-the-client-still-
has-to-download,-in-base-ten-ASCII.
● compact:-Indicates-that-the-client-accepts-
compacted-responses.-The-peer-list-can-then-
be-replaced-by-a-6-bytes-per-peer.The-first-
4-bytes-are-the-host,-and-the-last-2-bytes-
are-ports.

The-tracker-then-responds-with-a-“text/plain”-
document-with-the-following-keys:

● failure-message:-If-present,-then-no-other-
keys-are-included.-The-value-is-a-human-
readable-error-message-as-to-why-the
● request-failed.
● warning-message:-Similar-to-failure-
message,-but-response-still-gets-processed.
● interval:-The-number-of-seconds-a-client-
should-wait-between-sending-regular-
requests-to-the-tracker.
● min-interval:-Minimum-announce-interval.
● tracker-id:-A-string-that-the-client-should-
send-back-with-its-next-announcement.
● complete:-Number-of-peers-with-the-complete-
file.
● incomplete:-number-of-non-seeding-peers-
(leechers)
● peers:-A-list-of-dictionaries-including:-
peer-id,-IP-and-ports-of-all-the-peers.
http-GET-"http://torrent.ubuntu.com:6969/announce?info_hash=%90%28%9F
%D3M%FC%1C%F8%F3%16%A2h%AD%D85L%853DX&peer_id=-PC0001-
706887310628&uploaded=0&downloaded=0&left=699400192&port=6889&compact
=1"
HTTP/1.0-200-OK
Content-Length:-363
Content-Type:-text/plain
Pragma:-no-cache

3.1-Async-HTTP

Python-does-not-come-with-a-built-in-support-
for-async-HTTP-and-requests-library-does-not-
implement-asyncio-either.-Scouting-around-the-
Internet-it-looks-like-most-use-aiohttp,-which-
implements-both-a-HTTP-client-and-server.

The-project-uses-aiohttp-in-the-
pieces.tracker.Tracker-class-for-making-the-
HTTP-request-to-the-tracker-announce-url.-A-
shortened-version-of-that-code-is-this:

async-def-connect(self,
--------------------first:-bool=None,
--------------------uploaded:-int=0,
--------------------downloaded:-int=0):
----params-=-{-...}
----url-=-self.torrent.announce-+-'?'-+-urlencode(params)

----async-with-self.http_client.get(url)-as-response:
--------if-not-response.status-==-200:
------------raise-ConnectionError('Unable-to-connect-to-tracker')
--------data-=-await-response.read()
--------return-TrackerResponse(bencoding.Decoder(data).decode())

The-method-is-declared-using-async-and-uses-the-
new-asynchronous-context-manager-async-to-allow-
being-suspended-while-the-HTTP-call-is-being-
made.-Given-a-successful-response,-this-method-
will-be-suspended-again-while-reading-the-
binary-response-data-await-response.read().-
Finally-the-response-data-is-wrapped-in-a-
TrackerResponse-instance-containing-the-list-of-
peers,-alternatively-an-error-message.

3.2-The-Loop

Everything-up-to-this-point-could-really-have-
been-made-synchronously,-but-now-that-we-are-
about-to-connect-to-multiple-peers-we-need-to-
go-
Asynchronous.
TorrentClient-is-something-like-a-work-
coordinator,-it-starts-by-creating-an-
async.Queue-which-will-hold-the-list-of-
available-peers-that-can-be-connected-to.

Then-it-constructs-N-number-of-
pieces.protocol.PeerConnection-which-will-
consume-peers-from-off-the-queue.-These-
PeerConnection-instances-will-wait-(await)-
until-there-is-a-peer-available-in-the-Queue-
for-one-of-them-to-connect-to-(not-blocking).

Let’s-have-a-look-at-this-loop:

async-def-start(self):
----self.peers-=-[PeerConnection(self.available_peers,
------------------------------------self.tracker.torrent.info_hash,
------------------------------------self.tracker.peer_id,
------------------------------------self.piece_manager,
------------------------------------self._on_block_retrieved)
--------------------for-_-in-range(MAX_PEER_CONNECTIONS)]

----#-The-time-we-last-made-an-announce-call-(timestamp)
----previous-=-None
----#-Default-interval-between-announce-calls-(in-seconds)
----interval-=-30*60

----while-True:
--------if-self.piece_manager.complete:
------------break
--------if-self.abort:
------------break

--------current-=-time.time()
--------if-(not-previous)-or-(previous-+-interval-<-current):
------------response-=-await-self.tracker.connect(
----------------first=previous-if-previous-else-False,
----------------uploaded=self.piece_manager.bytes_uploaded,
----------------downloaded=self.piece_manager.bytes_downloaded)

------------if-response:
----------------previous-=-current
----------------interval-=-response.interval
----------------self._empty_queue()
----------------for-peer-in-response.peers:
--------------------self.available_peers.put_nowait(peer)
--------else:
------------await-asyncio.sleep(5)
----self.stop()

Basically,-what-that-loop-does-is-to:

● Check-if-we-have-downloaded-all-pieces
● Check-if-user-aborted-download
● Make-a-announce-call-to-the-tracker-if-needed
● Add-any-retrieved-peers-to-a-queue-of-
available-peers
● Sleep-5-seconds

4. The-Peer-Protocol
Peers-are-other-users-participating-in-a-
torrent,-and-have-the-partial-file,-or-the-
complete-file-(known-as-a-seed).-Pieces-are-
requested-from-peers,-but-are-not-guaranteed-to-
be-sent,-depending-on-the-status-of-the-peer.-
BitTorrent-uses-TCP-(Transmission-Control-
Protocol)-ports-6881-6889-to-send-messages-and-
data-between-peers,-and-unlike-other-protocols,-
does-not-use-UDP-(User-Datagram-Protocol).

Lets-go-through-the-different-parts-of-the-peer-
protocol,-and-then-go-through-how-it-is-all-
implemented.

1. Start-a-TCP-connection-with-the-peer.-
This-is-like-starting-a-phone-call.
2. Complete-a-two-way-BitTorrent-
handshake.-“Hello?”-“Hello."
3. Exchange-messages-to-download-
pieces.-“I’d-like-piece-#231-please."

4.1-The-HandShake

We’ve-just-set-up-a-connection-with-a-peer,-but-
we-want-do-a-handshake-to-validate-our-
assumptions-that-the-peer

● can-communicate-using-the-BitTorrent-protocol
● is-able-to-understand-and-respond-to-our-
messages
● has-the-file-that-we-want,-or-at-least-
knows-what-we’re-talking-about

The-secret-to-a-good-BitTorrent-handshake-is-
that-it’s-made-up-of-five-parts:

➔ The-length-of-the-protocol-identifier,-
which-is-always-19-(0x13-in-hex).
➔ The-protocol-identifier,-called-the-pstr-
which-is-always-BitTorrent-protocol.
➔ Eight-reserved-bytes,-all-set-to-0.-We’d-
flip-some-of-them-to-1-to-indicate-that-we-
support-certain-extensions.-But-we-don’t,-
so-we’ll-keep-them-at-0.
➔ The-infohash-that-we-calculated-earlier-to-
identify-which-file-we-want
➔ The-Peer-ID-that-we-made-up-to-identify-
ourselves

Immediately-after-the-Handshake,-the-remote-
peer-may-send-a-BitField-message.-The-BitField-
message-serves-to-inform-the-client-on-which-
pieces-the-remote-peer-have.-Pieces-support-
receiving-a-BitField-message,-and-most-
BitTorrent-clients-seem-to-send-it---but-since-
pieces-currently-do-not-support-seeding,-it-is-
never-sent,-only-received.

The-BitField-message-payload-contains-a-
sequence-of-bytes-that-when-read-binary-each-
bit-will-represent-one-piece.-If-the-bit-is-1-
that-means-that-the-peer-have-the-piece-with-
that-index,-while-0-means-that-the-peer-lacks-
that-piece.-I.e.-Each-byte-in-the-payload-
represent-up-to-8-pieces-with-any-spare-bits-
set-to-0.

Each-client-starts-in-the-state-choked-and-not-
interested.-That-means-that-the-client-is-not-
allowed-to-request-pieces-from-the-remote-peer,-
nor-do-we-have-intent-of-being-interested.

● Choked:-A-choked-peer-is-not-allowed-to-
request-any-pieces-from-the-other-peer.
● Unchoked:-An-unchoked-peer-is-allowed-to-
request-pieces-from-the-other-peer.
● Interested:-Indicates-that-a-peer-is-
interested-in-requesting-pieces.
● Not-interested:-Indicates-that-the-peer-is-
not-interested-in-requesting-pieces.
● Consider-Choked:-and-Unchoked-to-be-rules-
and-Interested-and-Not-Interested-to-be-
intents-between-two-peers.

After-the-handshake-we-send-an-Interested-
message-to-the-remote-peer,-telling-that-we-
would-like-to-get-unchoked-in-order-to-start-
requesting-pieces.

Until-the-client-receives-an-Unchoke-message---
it-may-not-request-a-piece-from-its-remote-
peer---the-PeerConnection-will-be-choked-
(passive)-until-either-unchoked-or-disconnected.

The-following-sequence-of-messages-is-what-we-
are-aiming-for-when-setting-up-a-PeerConnection:

--------------Handshake
----client--------------->-peer----
--We-are-initiating-the-handshake
---------------Handshake

----client-<---------------peer----
--Comparing-the-info_hash-with-our-hash

---------------BitField
----client-<---------------peer----
--Might-be-receiving-the-BitField

--------------Interested
----client--------------->-peer----
--Let-peer-know-we-want-to-download

--------------Unchoke
----client-<---------------peer----
-Peer-allows-us-to-start-requesting-pieces

4.2-Requesting-pieces

As-soon-as-the-client-gets-into-an-unchoked-
state-it-will-start-requesting-pieces-from-the-
connected-peer.-

If-we-know-that-the-other-peer-has-a-given-
piece,-we-can-send-a-Request-message-asking-the-
remote-peer-to-send-us-data-for-the-specified-
piece.-If-the-peer-complies-it-will-send-us-a-
corresponding-Piece-message-where-the-message-
payload-is-the-raw-data.
This-client-will-only-ever-have-one-outstanding-
Request-per-peer-and-politely-wait-for-a-Piece-
message-until-taking-the-next-action.-Since-
connections-to-multiple-peers-are-open-
concurrently,-the-client-will-have-multiple-
Requests-outstanding-but-only-one-per-
connection.

If,-for-some-reason,-the-client-does-not-want-a-
piece-anymore,-it-can-send-a-Cancel-message-to-
the-remote-peer-to-cancel-any-previously-sent-
Request.

4.3-Implementation

The-PeerConnection-opens-a-TCP-connection-to-a-
remote-peer-using-asyncio.open_connection-to-
asynchronously-open-a-TCP-connection-that-
returns-a-tuple-of-StreamReader-and-a-
StreamWriter.-Given-that-the-connection-was-
created-successfully,-the-PeerConnection-will-
send-and-receive-a-Handshake-message.

Once-a-handshake-is-made,-the-PeerConnection-
will-use-an-asynchronous-iterator-to-return-a-
stream-of-PeerMessages-and-take-the-appropriate-
action.

Using-an-async-iterator-separates-the-
PeerConnection-from-the-details-on-how-to-read-
from-sockets-and-how-to-parse-the-BitTorrent-
binary-protocol.-The-PeerConnection-can-focus-
on-the-semantics-regarding-the-protocol---such-
as-managing-the-peer-state,-receiving-the-
pieces,-closing-the-connection.

This-allows-the-main-code-in-
PeerConnection.start-to-basically-look-like:

async-for-message-in-PeerStreamIterator(self.reader,-buffer):
----if-type(message)-is-BitField:
--------self.piece_manager.add_peer(self.remote_id,-message.bitfield)
----elif-type(message)-is-Interested:
--------self.peer_state.append('interested')
----elif-type(message)-is-NotInterested:
--------if-'interested'-in-self.peer_state:
------------self.peer_state.remove('interested')
----elif-type(message)-is-Choke:
--------...

An-asynchronous-iterator-is-a-class-that-
implements-the-methods-__aiter__-and-__anext__-
which-is-just-async-versions-of-Python’s-
standard-iterators-that-have-implemented-the-
methods,-__iter__-and-next.

The-BitTorrent-protocol-uses-messages-with-
variable-length,-where-all-messages-takes-the-
form:

<length><id><payload>
● length-is-a-4-byte-integer-value
● id-is-a-single-decimal-byte
● payload-is-variable-and-message-dependent

5.-Managing-the-pieces

So-far-we-have-only-discussed-pieces---pieces-
of-data-being-exchanged-by-two-peers.-It-turns-
out-that-pieces-are-not-the-entire-truth,-there-
is-one-more-concept---blocks.

A-piece-is,-unsurprisingly,-a-partial-piece-of-
the-torrents-data.-A-torrent’s-data-is-split-
into-N-number-of-pieces-of-equal-size-(except-
the-last-piece-in-a-torrent,-which-might-be-of-
smaller-size-than-the-others).-The-piece-length-
is-specified-in-the-.torrent-file.-Typically-
pieces-are-of-sizes-512-kB-or-less,-and-should-
be-a-power-of-2.

Pieces-are-still-too-big-to-be-shared-
efficiently-between-peers,-so-pieces-are-
further-divided-into-something-referred-to-as-
blocks.-Blocks-are-the-chunks-of-data-that-are-
actually-requested-between-peers,-but-pieces-
are-still-used-to-indicate-which-peer-that-has-
which-pieces.-If-only-blocks-should-have-been-
used-it-would-increase-the-overhead-in-the-
protocol-greatly-(resulting-in-longer-
BitFields,-more-Have-messages-and-
larger-.torrent-files).

A-block-is-2^14-(16384)-bytes-in-size,-except-
the-final-block-that-most-likely-will-be-of-a-
smaller-size.

Consider-an-example-where-a-.torrent-describes-
a-single-file-foo.txt-to-be-downloaded.

name:-foo.txt
length:-135168
piece-length:-49152
That-small-torrent-would-result-in-3-pieces:

piece-0:-49-52-bytes
piece-1:-49-152-bytes
piece-2:-36-864-bytes-(135168---49152---49152)
--------=-135-168

Now-each-piece-is-divided-into-blocks-in-sizes-
of-2^14-bytes:

piece-0:
----block-0:-16-384-bytes-(2^14)
----block-1:-16-384-bytes
----block-2:-16-384-bytes
----------=--49-152-bytes

piece-1:
----block-0:-16-384-bytes
----block-1:-16-384-bytes
----block-2:-16-384-bytes
----------=--49-152-bytes

piece-2:
----block-0:-16-384-bytes
----block-1:-16-384-bytes
----block-2:--4-096-bytes
----------=--36-864-bytes

total:-------49-152-bytes
----------+--49-152-bytes
----------+--36-864-bytes
----------=-135-168-bytes

Exchanging-these-blocks-between-peers-is-
basically-what-BitTorrent-is-about.-Once-all-
blocks-for-a-piece-are-done,-that-piece-is-
complete-and-can-be-shared-with-other-peers-
(the-Have-message-is-sent-to-connected-peers).-
And-once-all-pieces-are-complete-the-peer-
transform-from-a-downloader-to-only-be-a-seeder.

Two-notes-on-where-the-official-specification-
is-a-bit-off:

● The-official-specification-refers-to-both-
pieces-and-blocks-as-just-pieces-which-is-
quite-confusing.-The-unofficial-
specification-and-others-seem-to-have-agreed-
upon-using-the-term-block-for-the-smaller-
piece-which-is-what-we-will-use-as-well.
● The-official-specification-is-stating-
another-block-size-that-what-we-use.-Reading-
the-unofficial-specification,-it-seems-that-
2^14-bytes-is-what-is-agreed-among-
implementers---regardless-of-the-official-
specification.
5.1-The-Implementation
When-a-TorrentClient-is-constructed,-so-is-a-
PieceManager-with-the-responsibility-to:

● Determine-which-block-to-request-next
● Persisting-received-blocks-to-file
● Determine-when-a-download-is-complete.

When-a-PeerConnection-successfully-handshakes-
with-another-peer-and-receives-a-BitField-
message-it-will-inform-the-PieceManager-which-
peer-(peer_id)-that-has-which-pieces.-This-
information-will-be-updated-on-any-received-
Have-message-as-well.-Using-this-information,-
the-PeerManager-knows-the-collective-state-on-
which-pieces-are-available-from-which-peers.

When-the-first-PeerConnection-goes-into-an-
unchoked-state-it-will-request-the-next-block-
from-its-peer.-The-next-block-is-determined-by-
calling-the-method-PieceManager.next_request.

The-next_request-implements-a-very-simple-
strategy-on-which-piece-to-request-next.
● When-the-PieceManager-is-constructed-all-
pieces-and-blocks-are-pre-constructed-based-
on-the-piece-length-from-the-.torrent-meta-
info
● All-pieces-are-put-in-a-missing-list
● When-next_request-is-called,-the-manager-
will-do-one-of:
○ Re-request-any-previously-requested-
block-that-has-timed-out
○ Request-the-next-block-in-an-ongoing-
piece
○ Request-the-first-block-in-the-next-
missing-piece

This-way-the-blocks-and-pieces-will-be-
requested-in-order.-However,-multiple-pieces-
might-be-ongoing-based-on-which-piece-a-client-
has.

Since-pieces-aim-to-be-a-simple-client,-no-
effort-has-been-made-on-implementing-a-smart-or-
efficient-strategy-for-which-pieces-to-request.-
A-better-solution-would-be-to-request-the-
rarest-piece-first,-which-would-make-the-entire-
swarm-healthier-as-well.
Whenever-a-block-is-received-from-a-peer,-it-is-
stored-(in-memory)-by-the-PieceManager.-When-
all-blocks-for-a-piece-is-retrieved,-a-SHA1-
hash-is-made-on-the-piece.-This-hash-is-
compared-to-the-SHA1-hashes-include-in-
the-.torrent-info-dict---if-it-matches-the-
piece-is-written-to-disk.

When-all-pieces-are-accounted-for-(matching-
hashes)-the-torrent-is-considered-to-be-
complete,-which-stops-the-TorrentClient-closing-
any-open-TCP-connection-and-as-a-result-the-
program-exits-with-a-message-that-the-torrent-
is-downloaded.

6.-Bibliography

1.(1st-February-2017-08:39.)-BitTorrentSpecification,-
Available-at:-https://wiki.theory.org/index.php/
BitTorrentSpecification-(Accessed:-6th-May-2020).
2.Allen-Kim-()-How-to-make-your-own-bittorrent-
client,-Available-at:-https://allenkim67.github.io/
programming/2016/05/04/how-to-make-your-own-
bittorrent-client.html-(Accessed:-6th-May-2020).
3.Bram-Cohen-(Sat-Feb-4-12:58:40-2017-+0100)-The-
BitTorrent-Protocol-Specification,-Available-at:-
http://bittorrent.org/beps/bep_0003.html-(Accessed:-
4th-May-2020).
4.Jesse-Li-()-Building-a-BitTorrent-client-from-the-
ground-up,-Available-at:-https://blog.jse.li/posts/
torrent/-(Accessed:-7th-May-2020).
5.JOE-HAWES-()-The-BitTorrent-Protocol,-Available-at:-
https://www.morehawes.co.uk/the-bittorrent-protocol-
(Accessed:-5th-May-2020).
6.Markus-Eliasson-()-A-BitTorrent-client-in-Python-
3.5,-Available-at:-https://markuseliasson.se/
article/bittorrent-in-python/-(Accessed:-4th-May-
2020).

You might also like