PHP BitTorrent Announce Client

Sa, 07.03.2009 - 09:32 -- Daniel Espendiller

Bittorrent macht mittlerweile einen Großteil des weltweiten Datenverkehrs aus. Ohne eine Torrentdatei und einen dazugehörigen Tracker läuft hier nichts. Ich habe eine Klasse in PHP erstellt, welche die Daten aus einer Torrentdatei auslesen kann und eine Anfrage an den Tracker schickt, welcher schließlich die IP-Adressen ausspuckt.
Es läßt sich mit dieser Klassen ein kompletter Client gegenüber dem Tracker simulieren, vom Starten des Downloads bis zum fertigstellen.
Dateien werden bei diesem Vorgang nicht übertragen (wird wohl in PHP nicht machbar sein). Es soll hier nur um das Verständnis der Kommunikation zwischen Client und Tracker über das http-Protokoll und des Bencoding gehen.

Torrent-Information

Als Beispiel Torrent-Datei hab ich mir ein Debian Image genommen

Zeigt den Torrentname (in der Torrent Dateien, nicht den Dateinamen) und die aufgeführten Dateien in der Torrentdatei

$client= new TorrentClient("Torrentflux","debian-500-i386-DVD-1.iso.torrent");
echo $client->getTorrentName()."\r\n";
print_r($client->getTorrentFiles());

debian-500-i386-DVD-1.iso
Array
(
    [debian-500-i386-DVD-1.iso] => Array
        (
            [size] => 4698322944
        )
 
)

Weitere Torrent-Informationen stehen zur Verfügung z.B Hashwert, größe des gesamten Downloads und Trackerurl

$client= new TorrentClient("Torrentflux","debian-500-i386-DVD-1.iso.torrent");
echo "AnnounceUrl:".$client->getTorrentAnnounceUrl()."\r\n";
echo "Hash:".$client->getTorrentHash()."\r\n";
echo "Size:".$client->getTorrentSize()."\r\n";

AnnounceUrl:http://bttracker.debian.org:6969/announce
Hash:cf92138268871bc3bb964ed69db1ec36c2ce9759
Size:4698322944

Tracker response

Möchte man eine Trackeranfrage senden so geht das über announcing. getAnnoucedPeers stellt schließlich als Array die Peers über IP,Port und PeerID (soweit vorhanden) zur Verfügung. Da viele Tracker aus Performence gründen nur max. 50 Peers zur Verfügung stellen, gibt meist in der Antwort noch einen extra Wert für die gesamt Anzahl der Peers. Diesen Wert bekommt man über getAnnoucedPeersCount.
Bei dieser Anfrage wird dem Tracker ein Start-Event geschickt, wie es jeder Client machen würde.

$client= new TorrentClient("Torrentflux","debian-500-i386-DVD-1.iso.torrent");
$client->announcing();
 
echo "Peers on server:\r\n";
echo $client->getAnnoucedPeersCount()."\r\n";
 
echo "Peers to connect:\r\n";
print_r($client->getAnnoucedPeers());

Peers on server:
49
Peers to connect:
Array
(
    [0] => Array
        (
            [ip] => 68.231.xxx.xxx
            [port] => 9798
        )
 
    [1] => Array
        (
            [ip] => 89.248.xxx.xxx
            [port] => 12730
        )
...
)

Neben dem Start Event gibt es weiterhin noch update, stopped und complete. Hier müssen allerdings weitere Angaben übernommen werden. Daten wie PeerID,PeerKey,Client (Beispiel $ar) müssen der Anfrage aus dem Start-Event entsprechen. Eine Übergabe der Torrentdatei ist nicht erforderlich sichert man sich vorher die entsprechenden Daten.

$a= new TorrentClient($ar["Client"]);
$a->peer_id=$ar['PeerID'];
$a->peer_key=$ar['PeerKey'];
$a->an_event="update";
$a->an_download=$ar['DownloadedBytes'];
$a->an_upload=$ar['UploadedBytes'];
$a->an_left=($ar['LeftBytes'] - $ar['DownloadedBytes']);
$an=$a->announcing($ar["Hash"],$ar["AnnouceURL"]);

VCS File: 

/trunk/bittorrent_announce/bittorrent_announce_class.php