Class: RubyTorrent::Server

Inherits:
Object
  • 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