0Day Forums
How do I set the socket timeout in Ruby? - Printable Version

+- 0Day Forums (https://zeroday.vip)
+-- Forum: Coding (https://zeroday.vip/Forum-Coding)
+--- Forum: Ruby (https://zeroday.vip/Forum-Ruby)
+--- Thread: How do I set the socket timeout in Ruby? (/Thread-How-do-I-set-the-socket-timeout-in-Ruby)



How do I set the socket timeout in Ruby? - shopwindows381671 - 07-19-2023

How do you set the timeout for blocking operations on a Ruby socket?


RE: How do I set the socket timeout in Ruby? - lutanist884 - 07-19-2023

The timeout object is a good solution.

This is an example of asynchronous I/O (non-blocking in nature and occurs asynchronously to
the flow of the application.)

IO.select(read_array
[, write_array
[, error_array
[, timeout]]] ) => array or nil

Can be used to get the same effect.

require 'socket'

strmSock1 = TCPSocket::new( "www.dn.se", 80 )
strmSock2 = TCPSocket::new( "www.svd.se", 80 )
# Block until one or more events are received
#result = select( [strmSock1, strmSock2, STDIN], nil, nil )
timeout=5

timeout=100
result = select( [strmSock1, strmSock2], nil, nil,timeout )
puts result.inspect
if result

for inp in result[0]
if inp == strmSock1 then
# data avail on strmSock1
puts "data avail on strmSock1"
elsif inp == strmSock2 then
# data avail on strmSock2
puts "data avail on strmSock2"
elsif inp == STDIN
# data avail on STDIN
puts "data avail on STDIN"
end
end
end



RE: How do I set the socket timeout in Ruby? - clincher418 - 07-19-2023

I think the non blocking approach is the way to go.
I tried the mentioned above article and could still get it to hang.
this article [non blocking networking][1] and the jonke's approach above got me on the right path. My server was blocking on the initial connect so I needed it to be a little lower level.
the socket rdoc can give more details into the connect_nonblock


def self.open(host, port, timeout=10)
addr = Socket.getaddrinfo(host, nil)
sock = Socket.new(Socket.const_get(addr[0][0]), Socket::SOCK_STREAM, 0)

begin
sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
rescue Errno::EINPROGRESS
resp = IO.select([sock],nil, nil, timeout.to_i)
if resp.nil?
raise Errno::ECONNREFUSED
end
begin
sock.connect_nonblock(Socket.pack_sockaddr_in(port, addr[0][3]))
rescue Errno::EISCONN
end
end
sock
end


to get a good test. startup a simple socket server and then do a ctrl-z to background it

the IO.select is expecting data to come in on the input stream within 10 seconds. this may not work if that is not the case.

It should be a good replacement for the TCPSocket's open method.


[1]:

[To see links please register here]

[2]:

[To see links please register here]




RE: How do I set the socket timeout in Ruby? - ariajbkg - 07-19-2023

The solution I found which appears to work is to use [Timeout::timeout](

[To see links please register here]

):

require 'timeout'
...
begin
timeout(5) do
message, client_address = some_socket.recvfrom(1024)
end
rescue Timeout::Error
puts "Timed out!"
end