Estoy revisando los documentos y los howtos que encuentro sobre el uso correcto de IO :: Select en términos de comunicaciones de socket de red. Creo que tengo la cabeza alrededor de la mayor parte.¿Cómo hago el correcto manejo de errores IO :: Select?
Sin embargo, todavía estoy un poco confuso sobre el manejo correcto de errores. Supongamos que tengo algo similar al siguiente código que se ejecuta dentro de un objeto. Sí, me doy cuenta de que es complicado, debería integrar IO :: Select en el objeto y no el socket fh en sí mismo, no debería recrear el IO :: Select cada vez que pasa el ciclo, estoy iterando sobre lo que solo puedo ser un único identificador de archivo devuelto, etc. Sin embargo, esto mantiene el ejemplo simple.
Esto es solo un cliente que se conecta a un servidor, pero que quiero ser capaz de manejar adecuadamente los errores de nivel de red como la pérdida de paquetes.
Edit: $self->sock()
devuelve solo un socket IO :: Socket :: INET abierto.
sub read {
my $self = shift;
my($length) = @_; ### Number of bytes to read from the socket
my $ret;
while (length($ret) < $length) {
my $str;
use IO::Select;
my $sel = IO::Select->new($self->sock());
if (my @ready = $sel->can_read(5)) { ### 5 sec timeout
for my $fh (@ready) {
my $recv_ret = $fh->recv($str, $length - length($ret));
if (!defined $recv_ret) {
MyApp::Exception->throw(
message => "connection closed by remote host: $!",
);
}
}
}
else {
### Nothing ready... we timed out!
MyApp::Exception->throw(
message => "no response from remote host",
);
}
$ret .= $str;
}
return $ret;
}
- ¿Es necesario estar marcando la vuelta de recv, o son errores que afectarían que va a aparecer en el IO :: Seleccionar objeto?
- ¿Manejo correctamente los tiempos de espera, o mi lógica está mal configurada?
- IO :: Socket hace mención de una excepción existente en un socket filehandle, para errores fuera de banda y otros problemas. ¿Debo verificar esto en caso de un tiempo de espera? ¿Cómo? ¿O no es importante y está bien ignorarlo?
- ¿Hay algún otro caso de excepción que deba manejar para un comportamiento correcto?
¿Por qué esperas reunir una "longitud mínima" de datos? Y si sock() devuelve una matriz de manejadores de archivos, obtendrá una combinación de respuestas de todos los sockets en orden aleatorio, ¿está bien? – Dallaylaen
Espero recopilar una cantidad mínima de datos porque este host remoto responde a un comando. En lugar de cambiar todo el búfer, estoy cambiando de un byte para determinar la longitud del siguiente fragmento, un fragmento, y continuar hasta que termine la codificación de comunicación. – Oesor