Class: BasicSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/tagen/socket.rb

Constant Summary collapse

MessageLengthError =
Class.new(StandardError)
MessageUnderflow =
Class.new(StandardError)
MAXLEN =
65535
LEN_LEN =
[0].pack("N").size

Instance Method Summary collapse

Instance Method Details

#recv2Object

Receive a message from the socket. Returns “” when there are no more messages (the writer has closed its end of the socket). Yields each time more data is received, even if partial. This can be used for a progress indicator.



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
# File 'lib/tagen/socket.rb', line 25

def recv2
  if (data = recv(LEN_LEN))
    if data.empty?
      ""
    else
      len = data.unpack("N")[0]
      if len > MAXLEN
        raise MessageLengthError, "MAXLEN exceeded: #{len} > #{MAXLEN}"
      end

      msg = ""
      part = nil
      while (delta = len - msg.length) > 0 and (part = recv(delta))
        if part.length == 0
          raise MessageUnderflow,
            "Peer closed socket before finishing message --" +
            " received #{msg.length} of #{len} bytes:\n" +
            msg[0..99].unpack("H*")[0] + "..."
        end
        yield part if block_given?
        msg << part
      end
      msg.empty? ? nil : msg
    end
  end
end

#recv_objObject



56
57
58
# File 'lib/tagen/socket.rb', line 56

def recv_obj
  Marshal.load recv2
end

#send2(message) ⇒ Object

Send a message over the socket. The message is like a datagram rather than a stream of data.



12
13
14
15
16
17
18
19
# File 'lib/tagen/socket.rb', line 12

def send2(message)
  len = message.length
  if len > MAXLEN
    raise MessageLengthError, "MAXLEN exceeded: #{len} > #{MAXLEN}"
  end
  send([len].pack("N"), 0)
  send(message, 0)
end

#send_obj(obj) ⇒ Object



52
53
54
# File 'lib/tagen/socket.rb', line 52

def send_obj(obj)
  send2 Marshal.dump(obj)
end