Class: QuartzTorrent::UdpTrackerDriver
- Inherits:
-
TrackerDriver
- Object
- TrackerDriver
- QuartzTorrent::UdpTrackerDriver
- Defined in:
- lib/quartz_torrent/udptrackerdriver.rb
Overview
A tracker driver that uses the UDP protocol as defined by xbtt.sourceforge.net/udp_tracker_protocol.html
Constant Summary collapse
- ReceiveLength =
Set UDP receive length to a value that allows up to 100 peers to be returned in an announce.
620
Instance Method Summary collapse
-
#initialize(announceUrl, infoHash, timeout = 2) ⇒ UdpTrackerDriver
constructor
A new instance of UdpTrackerDriver.
- #request(event = nil) ⇒ Object
Constructor Details
#initialize(announceUrl, infoHash, timeout = 2) ⇒ UdpTrackerDriver
Returns a new instance of UdpTrackerDriver.
6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/quartz_torrent/udptrackerdriver.rb', line 6 def initialize(announceUrl, infoHash, timeout = 2) super() @announceUrl = announceUrl @infoHash = infoHash @timeout = timeout @logger = LogManager.getLogger("udp_tracker_client") if @announceUrl =~ /udp:\/\/([^:]+):(\d+)/ @host = $1 @trackerPort = $2 else throw "UDP Tracker announce URL is invalid: #{announceUrl}" end end |
Instance Method Details
#request(event = nil) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/quartz_torrent/udptrackerdriver.rb', line 20 def request(event = nil) if event == :started event = UdpTrackerMessage::EventStarted elsif event == :stopped event = UdpTrackerMessage::EventStopped elsif event == :completed event = UdpTrackerMessage::EventCompleted else event = UdpTrackerMessage::EventNone end socket = UDPSocket.new result = nil begin socket.connect @host, @trackerPort @logger.debug "Sending UDP tracker request to #{@host}:#{@trackerPort}" # Send connect request req = UdpTrackerConnectRequest.new socket.send req.serialize, 0 resp = UdpTrackerConnectResponse.unserialize(readWithTimeout(socket,ReceiveLength,@timeout)) @logger.debug "Connect response: #{resp.inspect}" raise "Invalid connect response: response transaction id is different from the request transaction id" if resp.transactionId != req.transactionId connectionId = resp.connectionId dynamicParams = @dynamicRequestParamsBuilder.call # Send announce request req = UdpTrackerAnnounceRequest.new(connectionId) req.peerId = dynamicParams.peerId req.infoHash = @infoHash req.downloaded = dynamicParams.downloaded req.left = dynamicParams.left req.uploaded = dynamicParams.uploaded req.event = event #req.port = socket.addr[1] req.port = dynamicParams.port socket.send req.serialize, 0 resp = UdpTrackerAnnounceResponse.unserialize(readWithTimeout(socket,ReceiveLength,@timeout)) @logger.debug "Announce response: #{resp.inspect}" peers = [] resp.ips.length.times do |i| ip = resp.ips[i].unpack("CCCC").join('.') port = resp.ports[i].unpack("n").first peers.push TrackerPeer.new ip, port end peers result = TrackerResponse.new(true, nil, peers) result.interval = resp.interval if resp.interval rescue result = TrackerResponse.new(false, $!, []) ensure socket.close if ! socket.closed? end result end |