ruby network-programming

¿Cómo configuro el tiempo de espera del socket en Ruby?



network-programming (3)

Creo que el enfoque de no bloqueo es el camino a seguir.
Probé el artículo mencionado anteriormente y aún así pude colgarlo.
este artículo que no bloquea las redes y el enfoque anterior de jonke me llevaron por el camino correcto. Mi servidor estaba bloqueando en la conexión inicial, así que necesitaba que fuera un nivel un poco más bajo.
el socket rdoc puede dar más detalles en 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

para obtener una buena prueba. iniciar un servidor de socket simple y luego hacer un ctrl-z para fondo

IO.select espera que los datos entren en la secuencia de entrada en 10 segundos. esto puede no funcionar si ese no es el caso.

Debería ser un buen reemplazo para el método abierto de TCPSocket.

¿Cómo se configura el tiempo de espera para bloquear operaciones en un socket Ruby?


El objeto de tiempo de espera es una buena solución.

Este es un ejemplo de E / S asíncrona (de naturaleza no bloqueante y se produce de forma asíncrona al flujo de la aplicación).

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

Puede usarse para obtener el mismo efecto.

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


La solución que encontré que parece funcionar es usar Timeout :: timeout :

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