class Torrenter::Peer::BufferState
Attributes
piece[R]
Public Class Methods
new(socket, info_hash)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 13 def initialize(socket, info_hash) @socket = socket @buffer = '' @info_hash = info_hash end
Public Instance Methods
bitfield()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 74 def bitfield unpack('B').first.split('') end
current_piece=(type)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 54 def current_piece=(type) @piece.status = type if @piece end
hash_matches?()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 58 def hash_matches? @buffer[28..47] == @info_hash end
have() { |unpack('C').last| ... }
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 70 def have yield unpack('C').last end
messager(index, blk)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 19 def messager(index, blk) if @buffer.empty? recv else case @buffer[4] when nil @buffer.slice!(0..3) if @buffer[0..3] == KEEP_ALIVE when HANDSHAKE parse_handshake when BITFIELD bitfield.each_with_index do |bit, i| blk.call(i, @socket) if bit == '1' end send_interested if @buffer.empty? when HAVE if @buffer.bytesize < 9 recv else have { |i| blk.call(i, @socket) } end send_interested if @buffer.empty? when INTERESTED parse_interested(index) when PIECE parse_piece(index) when CANCEL @socket.close else recv send(KEEP_ALIVE) end end end
packet_length?()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 111 def packet_length? @buffer.size >= msg_length + 4 end
parse_handshake() { || ... }
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 62 def parse_handshake if !hash_matches? yield else @buffer.slice!(0..67) end end
parse_interested(index)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 87 def parse_interested(index) if interested? pick_piece(index) request_piece if @piece else @socket.close end end
parse_piece(index)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 96 def parse_piece(index) if packet_length? @piece << @buffer.slice!(13..-1) @buffer.clear if @piece.complete? @piece.write_to_file @piece = nil pick_piece(index) unless index.all? end request_piece else recv end end
pick_piece(index)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 78 def pick_piece(index) @piece = index.find_least(@socket) if @piece puts "#{@piece.index} selected by #{@socket}." else puts "No piece selected!" end end
piece_selected?()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 140 def piece_selected? @piece end
recv(bytes=BLOCK)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 127 def recv(bytes=BLOCK) begin @buffer << @socket.recv_nonblock(bytes) rescue *EXCEPTIONS '' rescue Errno::ETIMEDOUT if piece_selected? @piece.status = :available end @socket.close end end
request_piece()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 115 def request_piece send pack(13, "\x06", @piece.index, @piece.chunk, @piece.block) if @piece end
send(msg)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 119 def send(msg) begin @socket.sendmsg_nonblock(msg) rescue *EXCEPTIONS @socket.close end end
Private Instance Methods
interested?()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 162 def interested? @buffer.slice!(0..4) == "\x00\x00\x00\x01\x01" end
msg_length()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 158 def msg_length @buffer[0..3].unpack("N*").last end
pack(*msg)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 150 def pack(*msg) msg.map { |m| m.is_a?(Integer) ? [m].pack("I>") : m }.join end
send_interested()
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 146 def send_interested send("\x00\x00\x00\x01\x02") end
unpack(type)
click to toggle source
# File lib/torrenter/peer/buffer_state.rb, line 154 def unpack(type) @buffer.slice!(0...msg_length + 4)[5..-1].unpack("#{type}*") end