On 1/31/06, ara.t.howard / noaa.gov <ara.t.howard / noaa.gov> wrote:
> On Wed, 1 Feb 2006, Mark Volkmann wrote:
>
> > How can I write non-string data using the IO class?
> > In particular, I'd like to write an integer across a socket connection.
> > All the methods I see in IO for writing either only write strings or
> > only write the to_s version of an object, which is of course a string.
>
> see String#unpack and Array#pack.
>
> you probably want something like
>
>    socket.write [42].pack("N")

Thanks!  I wasn't aware of pack/unpack. I still can't get this simple
example to work though. I'm wondering if I need to use puts and gets.
If I use write, I'm not sure if the other end will know how many bytes
to read. Can you spot anything I'm doing wrong? The client sends
integers to the server. The server computes the average and returns
it. Currently the server only gets two of the three ints and the
client says "'gets': Invalid argument".

-----------
client.rb
-----------

require 'socket'

# Create socket.
host, port = 'localhost', 1919
socket = TCPSocket.new(host, port)

# Send request message.
binary_string = [19, 10, 8].pack('N*')
socket.puts binary_string

# Get response message.
binary_string = socket.gets
avg = binary_string.unpack('g') # float
puts "avg = #{avg}"

socket.close

------------
server.rb
------------

require 'socket'

# Create server.
host, port = 'localhost', 1919
server = TCPServer.new(host, port)

# Process connection requests.
loop do
  session = server.accept
  break if server == nil

  # Process session requests.
  binary_string = session.gets
  values = binary_string.unpack('N*')
  sum = 0
  values.each { |value| sum += value }
  puts "sum = #{sum}"
  puts "size = #{values.size}"

  avg = sum.to_f / values.size

  binary_string = [avg].pack('g') # float
  session.puts(binary_string)
  session.close
end

--
R. Mark Volkmann
Partner, Object Computing, Inc.