Skip to content

7Kruk7/Bit-Torrent-In-Csharp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BitTorrent Client

A BitTorrent client built from scratch in C# following the BitTorrent protocol specification. The project implements the core protocol: bencode parsing, torrent file reading, tracker communication, peer wire protocol, and piece management with SHA1 verification.

Built as a learning project to understand peer-to-peer networking, binary protocols, and concurrent programming. Based on Sean O'Flynn's tutorial, restructured with clean architecture, SOLID principles, and design patterns.

Architecture

The project is organized into six layers, each with a single responsibility:

bitTorrent/
├── BEncoding/          Bencode parser (decode + encode)
│   ├── AST.cs              Value types: string, integer, list, dictionary
│   ├── ByteReader.cs        Cursor over byte arrays
│   ├── IBencodeParser.cs    Parser interface
│   └── BEncodingParser.cs   Recursive descent parser
│
├── Torrent/            Torrent metadata
│   ├── FileItem.cs          File path, size, offset
│   ├── Torrent.cs           Immutable metadata container
│   └── TorrentParser.cs     Converts parsed bencode to Torrent object
│
├── PieceManager/       Disk I/O and verification
│   └── PieceManager.cs      Read/write blocks, SHA1 piece verification
│
├── Tracker/            Tracker communication
│   ├── ITracker.cs          Tracker interface (Open/Closed principle)
│   ├── TrackerResponse.cs   Peer list and request interval
│   └── HttpTracker.cs       HTTP tracker implementation
│
├── Peer/               Peer wire protocol
│   ├── MessageType.cs       Protocol message type enum
│   ├── PeerMessageCodec.cs  Binary message encoding/decoding
│   ├── DataRequest.cs       Block request data
│   ├── DataPackage.cs       Block received data
│   └── Peer.cs              TCP connection, state, send/receive
│
├── Client/             Engine that ties everything together
│   ├── TorrentClient.cs     Orchestrates trackers, peers, downloads, uploads
│   └── Throttle.cs          Bandwidth limiting
│
└── Program.cs          Entry point

How it works

  1. Parse a .torrent file using the bencode decoder into a Torrent object containing metadata, piece hashes, and tracker URLs.

  2. Announce to trackers, sending the torrent's infohash (SHA1 of the encoded info dictionary). The tracker responds with a list of peer IP addresses.

  3. Connect to peers over TCP. Both sides exchange handshakes (verifying they're talking about the same torrent) and bitfields (communicating which pieces each side has).

  4. Download by requesting blocks from peers that have pieces we need. Pieces are selected by a scoring algorithm that prioritizes completion progress, rarity, and randomness.

  5. Verify each completed piece by computing its SHA1 hash and comparing against the hash from the torrent file. If verification fails, the piece is re-downloaded.

  6. Upload pieces to other peers that request them, with bandwidth throttling.

Design decisions

Separation of concerns over tutorial simplicity. The original tutorial puts everything in a monolithic Torrent class. This project splits responsibilities: Torrent holds metadata, PieceManager handles disk I/O, TorrentParser handles parsing, and TorrentClient orchestrates.

Interfaces for extensibility. IBencodeParser and ITracker allow swapping implementations without changing dependent code. For example, adding a UDP tracker only requires a new UdpTracker class implementing ITracker.

Dependency injection. Classes receive their dependencies through constructors rather than creating them internally. TorrentParser receives an IBencodeParser, HttpTracker receives an IBencodeParser.

Immutable data objects. Torrent, FileItem, and the bencode AST types are immutable after construction, preventing accidental mutation of shared state.

Binary data preservation. BencodeString stores raw byte[] internally, not string, because bencode "strings" often contain binary data (SHA1 hashes) that would be corrupted by UTF-8 encoding/decoding.

Concepts covered

  • Bencode encoding/decoding — recursive descent parser, round-trip verified
  • SHA1 hashing — infohash computation, piece verification
  • TCP networking — async reads, message framing over a byte stream
  • Binary protocol — big-endian integer encoding, bitfield manipulation
  • Multithreading — concurrent dictionaries, interlocked operations, thread-safe throttling
  • File I/O — reading/writing across file boundaries, piece-to-file offset mapping

Running

dotnet build
dotnet run --project bitTorrent -- 6881 path/to/file.torrent path/to/download/directory

Testing

dotnet test

75 unit tests covering bencode parsing, byte reader, message codec, piece manager, and AST types.

Limitations

This is a learning implementation of BitTorrent v1.0. It does not include:

  • UDP tracker protocol (only HTTP trackers)
  • DHT (distributed hash table) for trackerless operation
  • Peer exchange (PEX)
  • Encryption (MSE/PE)
  • UPnP/NAT-PMP for port forwarding
  • Resume/pause functionality
  • Multi-torrent support

References

About

BitTorrent client built from scratch in C# – bencode parser, peer wire protocol, SHA1 piece verification, and tracker communication with clean layered architecture.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages