RubyTorrent 0.1

RubyTorrent 0.1 (BitTorrent for Ruby) is out. It has a host of bug-fixes and new features: works on Windows, for one, and now has snubbing support (sort of) and a nicer API.

Seeing as how I had never, ever tested RubyTorrent on Windows during development, I figured it was going to be a nightmare trying to port it. But the out the only change I had to make was adding a “b” flag to all my calls (lame). The part of me that says “networking libraries should be written in C!” dies a little every day.

The command-line client is now completely usable (give it a .torrent, wait, and tada! there’s your file) and a little more interesting to watch than before. I’m using that as my main protocol debugging tool at the moment, so expect changes and improvments.

The API definitely needs some more work, but it’s pretty cute at the moment:

  ## world's smallest bittorrent client
  require 'rubytorrent'

  bt =
  thread = do
    while true
      puts bt.percent_completed
      sleep 15

  bt.on_complete { thread.kill }

As for snubbing: BitTorrent snubbing, like end-game mode, doesn’t really seem to be documented anywhere. Every page about the BitTorrent protocol I’ve found just echoes (or more often, repeats verbatim) the ambiguities on the wiki or in Bram’s “documentation”. For example, none of them really make clear:

  1. Is snubbing done based on an individual peer’s actions or on all (unchoked?) peers’ actions?
  2. Is the choking flag sent when a peer is snubbed?
  3. How, exactly, is optimistic unchoking affected by a snubbed peer?
  4. When should end-game mode be triggered? 10 blocks left? 5% of the file left? 25%? 100 blocks?

I’ve filled in the gaps with what I think is reasonable: 15 blocks left triggers end-game mode, and snubbing is basically a tit-for-tat response that forces a choke but which increments the total number of peers which can be optimistically unchoked. And my plan is to sit back, watch download after download go by, and tweak things until I’m happy.