On Mon, Aug 20, 2012 at 11:57 AM, tammy roberts2 <[email protected]> wrote:
> Hi Robert, it is me again, my computer crashed and I lost my login
> information. Here is what I am using right now, it seems to be working
> fine, but maybe you see problems with it or a way to improve. Also maybe
> it will help someone else out who is struggling with the same problem I
> was.

This is a completely different approach: you do not use a termination
byte any more but transmit the message length beforehand.
>
> class Networking
>
>   def initialize
>     @settings = Settings.new
>   end
>
>   def listen(server)
>     loop do
>       Thread.start(server.accept) do |client|
>         data_received = []
>         total_received = 0
>         incoming_data_size = client.recvfrom( 4 )[0].unpack('N*')[0]
>
>         loop do
>           section_size = client.recvfrom( 4 )[0].unpack('N*')[0]
>           message_section = ""
>
>           loop do
>             message_section << client.recvfrom( section_size )[0]
>             break if message_section.bytesize == section_size
>           end
>
>           data_received << message_section
>           total_received += 4 + message_section.bytesize
>           break if total_received == incoming_data_size
>         end
>
>     yield(data_received, client)
>       end
>     end
>   end
>
>   def send_data(socket, message)
>     forward_message = [message.bytesize].pack('N*') + message
>     socket.send(forward_message, 0)
>     yield(socket)
>   end

Why do you yield the socket?

>   def get_reply(socket)
>     incoming_data_size = socket.recvfrom( 4 )[0].unpack('N*')[0]
>     section_size = socket.recvfrom( 4 )[0].unpack('N*')[0]
>     reply = ""
>
>     loop do
>       reply << socket.recvfrom( section_size )[0]
>       break if reply.bytesize == incoming_data_size - 4
>     end
>
>     yield(reply, socket)
>   end
> end

If you use #send then I'd also use #read for reading instead of
#recvfrom.  I'd only use that method if I needed the extra options.
Method #read will also block until as many bytes have arrived so you
do not take care of fragment messages yourself.

I'd probably choose a tad different approach by wrapping the
connection with something that does the message handling and creation
of a message type (for specific parsing etc.):

# could be more sophisticated
Message = Struct.new :bytes

Connection = Struct.new :socket do
  def send(msg)
    b = msg.bytes
    socket.write [b.bytesize].pack 'N'
    socket.write b
    self
  end

  def close
    socket.close
  end

  def each_msg
      until socket.eof?
        size = socket.read(4).unpack('N').first
        msg = socket.read(size)
        yield Message.new(msg)
      end
    end

    self
  end
end

loop do
  Thread.new(server.accept) do |client|
    conn = Connection.new client

    conn.each_msg do |msg|
      yield msg, conn
    end
  end
end


Kind regards

robert


-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

-- You received this message because you are subscribed to the Google Groups 
ruby-talk-google group. To post to this group, send email to 
[email protected]. To unsubscribe from this group, send email 
to [email protected]. For more options, visit this 
group at https://groups.google.com/d/forum/ruby-talk-google?hl=en

Reply via email to