Class PacketIO
In: lib/network/packetio.rb
Parent: SockIO
PacketIO
SockIO
dot/f_28.png

The PacketIO class implements a mechanism to send and recv packets delimited by a length prefix which is assumed to be a 4 bytes integer in network byte order.

Methods

new   read   write  

Public Class methods

Creates a new PackIO object

sock
The socket which will be used
bufsize
The size of the buffer to use (default is 16K)

[Source]

# File lib/network/packetio.rb, line 29
  def initialize(sock, bufsize=16380)
    @sock = sock
    @bufsize = bufsize + 4 # round out with prefix bytes
    @inbuffer = ""
    @outbuffer = ""
    @packet_size = 0
    @prefix_found = false
  end

Public Instance methods

read will receive a data from the socket.

return
The data read
IOError
A sockets error occurred.
EOFError
The connection has closed normally.

[Source]

# File lib/network/packetio.rb, line 43
  def read
    @inbuffer << @sock.recv(@bufsize)
    if !@prefix_found
      # start of packet
      if @inbuffer.size >= 4
        sizest = @inbuffer.slice!(0..3)
        @packet_size = sizest.unpack("N")[0]
        @prefix_found = true
        if @packet_size > @bufsize
          @inbuffer = ""
          @packet_size = 0
          @prefix_found = false
          log.warn "Discarding packet: Buffer size exceeded (PACKETSIZE=#{@packet_size} STRING='#{sizest}')"
          return nil
        end
      else
        return nil # not enough data yet
      end
    end

    if @prefix_found
      if @inbuffer.size >= @packet_size
        # We have it
        @prefix_found = false
        ps = @packet_size
        @packet_size = 0
        return @inbuffer.slice!(0...ps).chop  # chop off NUL
      else
        # Dont have it all yet.
        return nil
      end
    end
  end

write will transmit a packet to the socket, we calculated the size here

msg
The message string to be sent.
return
false if more data to be written, true if all data written
IOError
A sockets error occurred.
EOFError
The connection has closed normally.

[Source]

# File lib/network/packetio.rb, line 83
  def write(msg)
    if !msg.nil? && !msg.empty?
      @outbuffer << [msg.length].pack("N") << msg
    end
    n = @sock.send(@outbuffer, 0)
    # save unsent data for next call
    @outbuffer.slice!(0...n)
    @outbuffer.size == 0
  rescue Exception
    @outbuffer = ""  # Does it really matter?
    raise
  end

[Validate]