Hi all -
I'm extremely new to Ruby programming. Forgive me.
I'm trying to develop an updated Net::TFTP library. The existing
library doesn't seem to work correctly with the few embedded devices
that I've tried it with. It's quite old and uses Timeout::timeout()
while waiting on IO, and this never, ever seems to work (timeout
exception is always thrown, whether I am writing or reading).
I've been rewriting the library to use IO.select() in place of all of
the old Timeout::timeout() statements. I'm finding that its behavior is
really weird, though.
Here is my snippet of modified Net::TFTP.putbinaryfile:
def putbinary(remotefile, io, &block) # :yields: data, seq
s = UDPSocket.new
peer_ip = IPSocket.getaddress(@host)
puts "putting binary file to ", peer_ip
peer_tid = nil
seq = 0
from = nil
data = nil
while TRUE do
s.send(wrq_packet(remotefile, "octet"), 0, peer_ip, @port)
puts "(Re-)Sent fwrite request, waiting for response"
a = IO.select([s], nil, nil, 1)
if a
puts "."
packet, from = s.recvfrom(2048,0)
puts "."
puts "received packet " , packet, " from ", from
next unless peer_ip == from[3]
type, block, data = scan_packet(packet)
break if (type == OP_ERROR) || (type == OP_OPACK) || ((type ==
OP_ACK) && (block == seq))
end
end
My output is:
<I see the write request packet go out via wireshark>
<0.04 seconds later, I see an ACK from the tftp server>
Sent fwrite request, waiting for response
.
<The program then pauses for 5 seconds>
.
received packet....yadda yadda yadda
The same delay occurs when I actually send packets of the file (and if
the file is big, the 5-second delays between blocks is horrifyingly
slow).
It seems that recvfrom() still blocks, even though IO.select should not
return a non-nil response unless there is data to be read on the socket?
Setting different maximum sizes to recvfrom() doesn't change the
behavior.
I wrote a separate program doing the exact same thing with IO.select()
followed by recvfrom(). It then s.send()'s the data back to the client,
basically making a UDP echo service. Connecting to that with netcat
yields exactly what I'd expect: the data is echo'd back to netcat
immediately, not after a several-second delay.
If it's any help, I'm running Ruby 1.8.7...
I'd appreciate any help that folks can provide, even if it's just a
pointer to some other documentation that I should read. From what I've
read, IO.select() should do what I want, though?
Thanks,
Reid
···
--
Posted via http://www.ruby-forum.com/.