Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

non-blocking sockets

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio
Mensaje Sab Ene 14, 2006 6:33 pm
SaToNiO
Perlero Nuevo
Perlero Nuevo
Registrado: 14 Ene 2006
Mensajes: 3
non-blocking sockets Responder citando

Código:
use IO::Socket::INET;

$remote_host1="irc.red-futura.org";
$remote_port1=6667;

$socket = IO::Socket::INET->new(PeerAddr => $remote_host1,
                                PeerPort => $remote_port1,
                                Proto    => "tcp",
                                Type     => SOCK_STREAM)
    or die "No pudo conectar \$socket : $! \n";


print $socket "USER weeee weeee weeee :el puto clon conectao dsd perl\nNICK elclonillo\n";

$sock2 = IO::Socket::INET->new(PeerAddr => "irc.irc-hispano.org",
                                PeerPort => 6667,
                                Proto    => "tcp",
                                Type     => SOCK_STREAM)
    or die "No pudo conectar \$sock2 : $! \n";

print $sock2 "USER weeee weeee weeee :el puto clon conectao dsd perl\nNICK elclonillo2\n";



$socket -> blocking(0);
$sock2  -> blocking(0);
# estas lineas son



$leer="";
$leer2="";
while (1) {
  $leer = <$socket>;
  $leer2 = <$sock2>;
  unless ($leer eq "") {
   chop($leer);
   @read=split(/ /,$leer);
   if (($read[1] eq "376") || ($read[1] eq "422")) {
      print $socket "join #hattrick\n";
   }
   if ($read[0] eq "PING") {
      print $socket "pong $read[1]\n";
   }
   if ($read[1] eq "PRIVMSG") {
      @nick=split(/!/,$read[0]);
      @nick=split(/:/,$nick[0]);
      $nick=$nick[1];
      if ("\L$nick" eq "satonio") {
         if ($read[3] eq ":!haz") {
            $orden="";
            for ($i=4;defined($read[$i]);$i++) {
               $orden="$orden $read[$i]";
            }
            print $socket $orden;
         }
      }
   }
   print "\$leer = $leer\n";
   $leer="";
  }
  unless ($leer2 eq "") {
   chop($leer2);
   @read=split(/ /,$leer2);
   if (($read[1] eq "376") || ($read[1] eq "422")) {
      print $sock2 "join #hattrick\n";
   }
   if ($read[0] eq "PING") {
      print $sock2 "pong $read[1]\n";
   }
   if ($read[1] eq "PRIVMSG") {
      @nick=split(/!/,$read[0]);
      @nick=split(/:/,$nick[0]);
      $nick=$nick[1];
      if ("\L$nick" eq "satonio") {
         if ($read[3] eq ":!haz") {
            $orden="";
            for ($i=4;defined($read[$i]);$i++) {
               $orden="$orden $read[$i]";
            }
            print $sock2 $orden;
         }
      }
   }
   print "\$leer2 = $leer2\n";
   $leer2="";
  }
}


en windows no va lo de ponerlo en non-blocking pero en ubuntu si, alguien sabe k puedo hacer pa k vaya en windows

si lo preferis se puede mirar el codigo coloreao http://pastebin.com/506062
Mensaje Sab Ene 14, 2006 11:37 pm
Perl user
Maestro Honorario
Maestro Honorario
Registrado: 03 Nov 2004
Mensajes: 385
Responder citando

Los tópicos de red siempre son dependientes de la plataforma lamentablemente, y según parece quieres hacer un bot para IRC, por qué no usar algo existente o aprender de técnicas utilizadas en ese proyecto?

Yo siempre opto por utilizar frameworks basados en eventos, ya que te permite un mejor control ( incluso cuando están basados en threads ) de las acciones.

Te recomiendo utilizar POE::Component::IRC ( puedes ver ejemplos en el POE Cookbook ), un componente del framework POE que te permite escribir aplicaciones para IRC con una modalidad orientada a eventos, muy sencillo de controlar. En segundo término te recomiendo utilizar Net::IRC.

Te voy a decir las primeras problemáticas que tienes en tu código:

1) No manejas CR/LF/CRLF correspondientemente a la plataforma.
2) No es portable tu código por eso no funciona de la misma manera en ambas plataformas.
3) El hecho de decir "Non-blocking" no es para Windows es incorrecto, el término non-blocking IO se utiliza para decir que un recurso no espera a que se liberen los recursos que utiliza, éste queda listo para utilizarse en cuanto es llamado.
4) De nuevo el código no es portable ni muy Perlesco que digamos Smile

Saludos,
Mensaje Dom Ene 15, 2006 6:20 am
SaToNiO
Perlero Nuevo
Perlero Nuevo
Registrado: 14 Ene 2006
Mensajes: 3
Responder citando

esto es un ejercicio simple para probar el funcionamiento d las cosas en perl, ya k soy nuevo utilizandolo. el problema es k no m hace ni caso windows cuando pasa por las lineas resaltadas.

¿como lo se? borro esas lineas en linux y sale el mismo resultado k cuando lo hago andar en windows, ademas de otras muchas pruebas que no voy a describir, por lo que dudo muchisimo k el problema sea de los CR/LF/CRLF

Que no sea muy perlesco eso sera verdad, soy nuevo utilizando perl, no te voy a decir que no. Lo de que no es portable, si es por los citados CR/LF/CRLF ya te digo que no creo que sea el problema, y si es otra cosa, te agradeceria que me lo dijeras.
Mensaje Dom Ene 15, 2006 6:29 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
Responder citando

Pregunta... ¿Has comprobado que el XP no esté filtrando esos puertos? ¿O no estarán filtrados por el cortafuegos/antivirus tuyo?
Mensaje Dom Ene 15, 2006 6:41 am
SaToNiO
Perlero Nuevo
Perlero Nuevo
Registrado: 14 Ene 2006
Mensajes: 3
Responder citando

no tengo puesto nada que actue ahi, pero aunque lo tuviese lo que no va son esas dos lineas en el xp, no el resto que es donde abro conexiones, mando datos y los recibo.
Mensaje Dom Ene 15, 2006 7:42 am
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4130
Ubicación: Valladolid, España
Responder citando

Todo lo que he encontrado me remite a lo mismo: Win32 NO tiene soporte para el modo no bloqueante de los sockets:
http://bugs.activestate.com/cgi-bin/bugzilla/show_bug.cgi?id=14560
http://brebiou.cshl.edu/viewcvs/mpc/site/perl_networking/errata.html?rev=1.2#ch13
Lo que me sorprende es que estemos en el 2006 y todo esto venga de antes del 2001...

Aquí lo tienes mucho mejor explicacado:
http://poe.perl.org/?POE_RFCs/Windows_NT_socket_compatibility

Naturalmente, google encontrarás mucho más enlaces:
http://www.google.es/search?hl=es&q=PERL+NONBLOCK+SOCKET+windows&btnG=B%C3%BAsqueda&meta=

Quizás la solución sea tan sencilla como esta:
Código:
use POSIX;
fcntl($sock, F_SETFL(), O_NONBLOCK());

pero yo no la he probado.
Lo que sí he leído es que el socket hay que ponerlo en modo "overlapped IO":
http://bugs.activestate.com/cgi-bin/bugzilla/show_bug.cgi?id=14518
pero ya no estoy seguro de cómo se puede hacer...

Prueba a utilizar este módulo: Net::Socket::NonBlock, que parece que está diseñado precisamente para eso.

El enlace definitivo sería este, donde, aparte de haber alguien que también está haciendo un irc, al final se dan unas cuantas soluciones para solventar esto.
Mensaje Dom Ene 15, 2006 12:24 pm
Perl user
Maestro Honorario
Maestro Honorario
Registrado: 03 Nov 2004
Mensajes: 385
Responder citando

SaToNiO escribió:
esto es un ejercicio simple para probar el funcionamiento d las cosas en perl, ya k soy nuevo utilizandolo. el problema es k no m hace ni caso windows cuando pasa por las lineas resaltadas.

¿como lo se? borro esas lineas en linux y sale el mismo resultado k cuando lo hago andar en windows, ademas de otras muchas pruebas que no voy a describir, por lo que dudo muchisimo k el problema sea de los CR/LF/CRLF

Que no sea muy perlesco eso sera verdad, soy nuevo utilizando perl, no te voy a decir que no. Lo de que no es portable, si es por los citados CR/LF/CRLF ya te digo que no creo que sea el problema, y si es otra cosa, te agradeceria que me lo dijeras.


Creo que no entendiste mi post, mi respuesta fué general, dije que es necesario manejar correctamente la parte de CR/LF no obstante tu "creas" que no es necesario.

Sobre tu problema principal te hice un par de recomendaciones ( obviamente módulos que hacen caso a las recomendaciones que te hice ) y te hice incapié de que problemas de NBIO son cuestiones dependientes de la plataforma, y que hay módulos que tienen un "workaround" muy bueno para solucionarlo, y el mejor te indiqué que es POE::Component::IRC.

explorer escribió:

Todo lo que he encontrado me remite a lo mismo: Win32 NO tiene soporte para el modo no bloqueante de los sockets:
http://bugs.activestate.com/cgi-bin/bugzilla/show_bug.cgi?id=14560
http://brebiou.cshl.edu/viewcvs/mpc/site/perl_networking/errata.html?rev=1.2#ch13
Lo que me sorprende es que estemos en el 2006 y todo esto venga de antes del 2001...


Como indiqué anteriormente, es obvio que Windows no maneja NBIO y a su vez trabaja muy poco async/IO, comenté también que siempre los problemas de red son dependientes de la plataforma y que hay buenos workarounds para ello.

Uno de los posts del foro comenté sobre uno de los flaws de Perl sobre el manejo de sockets y cuestiones de bits.

Saludos,
Publicar nuevo tema   Responder al tema    Foros de discusión -> Intermedio Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group