Class: RubyTorrent::Server

Inherits:
Object show all
Defined in:
lib/rubytorrent/server.rb

Overview

The Server coordinates all Packages available on the machine. It instantiates one Controller for each Package. It’s also responsible for the creation of all TCP connections—it sets up the TCP socket, receives incoming connections, validates handshakes, and hands them off to the appropriate Controller; it also creates outgoing connections (typically at Controllers’ requests) and sends the handshake.

Constant Summary collapse

VERSION =
0
PORT_RANGE =
(6881 .. 6889)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hostname = nil, port = nil, http_proxy = ENV["http_proxy"]) ⇒ Server

Returns a new instance of Server.



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/rubytorrent/server.rb', line 34

def initialize(hostname=nil, port=nil, http_proxy=ENV["http_proxy"])
  @http_proxy = http_proxy
  @server = nil
  if port.nil?
    @port = PORT_RANGE.detect do |p|
      begin
        @server = TCPServer.new(hostname, p)
        @port = p
      rescue Errno::EADDRINUSE
        @server = nil
      end
      !@server.nil?
    end
    raise Errno::EADDRINUSE, "ports #{PORT_RANGE}" unless @port
  else
    @server = TCPServer.new(hostname, port)
    @port = port
  end

  @id = "rubytor" + VERSION.chr + (1 .. 12).map { |x| rand(256).chr }.join
  @controllers = {}
end

Instance Attribute Details

#http_proxyObject (readonly)

Returns the value of attribute http_proxy.



29
30
31
# File 'lib/rubytorrent/server.rb', line 29

def http_proxy
  @http_proxy
end

#idObject (readonly)

Returns the value of attribute id.



29
30
31
# File 'lib/rubytorrent/server.rb', line 29

def id
  @id
end

#portObject (readonly)

Returns the value of attribute port.



29
30
31
# File 'lib/rubytorrent/server.rb', line 29

def port
  @port
end

Instance Method Details

#add_connection(name, cont, socket) ⇒ Object



64
65
66
67
68
69
70
71
72
# File 'lib/rubytorrent/server.rb', line 64

def add_connection(name, cont, socket)
  begin
    shake_hands(socket, cont.info_hash)
    peer = PeerConnection.new(name, cont, socket, cont.package)
    cont.add_peer peer
  rescue ProtocolError => e
    socket.close rescue nil
  end
end

#add_torrent(mi, package, dlratelim = nil, ulratelim = nil) ⇒ Object



59
60
61
62
# File 'lib/rubytorrent/server.rb', line 59

def add_torrent(mi, package, dlratelim=nil, ulratelim=nil)
  @controllers[mi.info.sha1] = Controller.new(self, package, mi.info.sha1, mi.trackers, dlratelim, ulratelim, @http_proxy)
  @controllers[mi.info.sha1].start
end

#ipObject



57
# File 'lib/rubytorrent/server.rb', line 57

def ip; @server.addr[3]; end

#shutdownObject



88
89
90
91
92
93
94
95
96
# File 'lib/rubytorrent/server.rb', line 88

def shutdown
  return if @shutdown
  @shutdown = true
  @server.close rescue nil

  @thread.join(0.2)
  @controllers.each { |hash, cont| cont.shutdown }
  self
end

#startObject



74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rubytorrent/server.rb', line 74

def start
  @shutdown = false
  @thread = Thread.new do
    begin
      while !@shutdown; receive; end
    rescue IOError, StandardError
      rt_warning "**** socket receive error, retrying"
      sleep 5
      retry
    end
  end
  self
end

#to_sObject



98
99
100
# File 'lib/rubytorrent/server.rb', line 98

def to_s
  "<#{self.class}: port #{port}, peer_id #{@id.inspect}>"
end