• Publicidad

bot IRC

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

bot IRC

Notapor primitivo » 2015-04-19 00:03 @044

Un saludo.

Me he encontrado con el siguiente problema, comparando un programa para IRC (bot) escrito en C tiene mayor eficiencia que el mismo que yo hago pero en Perl (bot).

Si escribo help en el privado del botijo (sería un comando) en repetidas ocasiones éste se cuelga y da las respuestas con dos segundos de atraso, pero si lo hago al programa de IRC (bot) escrito en C, va perfectamente, inmediato.

Un trozo de código y me dicen si es fallo mio, si necesito hacer 'nonblocking', si el socket está mal implementado, o definitivamente, me resigno.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. while (1) #bucle para mantener la conexión
  2. {
  3.      
  4.       $socket = IO::Socket::INET->new(
  5.               PeerAddr => $configuration->{'servidor'},
  6.               PeerPort => $configuration->{'puerto'},
  7.               Proto => 'tcp'
  8.       ) or die "Connection failed (Revise el estado del servidor remoto o el archivo services.conf)";
  9.       if ($starting eq "FALSE")
  10.       {
  11.           &connect;
  12.           $starting = "TRUE";
  13.       }    
  14.       while (<$socket>) #bucle para leer los datos recibidos por el socket
  15.       {
  16.             print $_;
  17.             my $bytes = $_;
  18.             @lectura = split(" ",$bytes);
  19.             if (($lectura[1] eq "PING") or ($lectura[1] eq "G"))
  20.             {
  21.                         reply_ping($lectura[2]);          
  22.             }
  23.             if (($lectura[1] eq "P") or ($lectura[1] eq "PRIVMSG"))
  24.             {
  25.                 if ($nchan->{'numeric'} eq $lectura[2])
  26.                 {
  27.                     sendMsg($configuration->{'copers'},"Estoy leyendo el sistema de privados");
  28.                 }
  29.                 elsif ($nadmin->{'numeric'} eq $lectura[2])
  30.                 {
  31.                     my $tmpCommand = lc($lectura[3]);
  32.                     $tmpCommand =~ s/^\W//;
  33.                     if ($acommands{$tmpCommand})
  34.                     {
  35.                         my $executeCommand = $acommands{$tmpCommand};
  36.                         $SIG{'KILL'} = sub { threads->exit(); };
  37.                         my $processCommand = threads->new(\&$executeCommand,$tmpCommand,"Valor2");
  38.                         $processCommand->join();
  39.                         $processCommand->kill('KILL');
  40.                         sendMsg($configuration->{'copers'},"probando");
  41.                     } else {
  42.                         sendMsg($configuration->{'copers'},"comando desconocido $lectura[3]");
  43.                     }
  44.                 }
  45.             }
  46. }
  47.  
  48. sub reply_ping
  49. {
  50.     my($send) = (shift);
  51.     print $socket qq(:$configuration->{'numeric'} Z $send\n);
  52.     $send = "";
  53. }
  54.  
  55. sub connect_pseudoClient
  56. {
  57.     my $pseudoclient = shift;
  58.     my $id = shift;
  59.     my $hs = shift;
  60.     my $modes = shift;
  61.     my $more = shift;
  62.     my $nm = shift;
  63.     my $desc = shift;
  64.     my $timer = time;
  65.     print $socket qq($configuration->{'numeric'} N $pseudoclient 1 $timer $id $hs $modes $more $nm :$desc\n);
  66.     print $socket qq($nm J $configuration->{'copers'}\n);
  67.     print $socket qq($nchan->{'numeric'} M $configuration->{'copers'} +o $nm\n);
  68. }
  69.  
  70. sub login
  71. {
  72.     $timer = time;
  73.     print $socket qq(PASS $configuration->{'password'}\n);
  74.     print $socket qq(SERVER $configuration->{'hostbots'} 1 $timer $timer P10 $configuration->{'numeric'}Q] +hs :$configuration->{'nombrered'}\n);
  75. }
  76.  
  77. sub stats
  78. {
  79.    my $time_out = time - $time;
  80.    my $pid = $$ + 1;
  81.    print "PID: $pid\n";
  82.    print "OS: $^O\n";
  83.    print "Kernel: $^V\n";
  84. }
  85.  
  86. sub connect
  87. {
  88.     login();
  89.     connect_pseudoClient($chanserv->{'nickname'},$chanserv->{'identd'},$chanserv->{'host'},$chanserv->{'modos'},$chanserv->{'nickname'},$nchan->{'numeric'},$chanserv->{'descripcion'});
  90.     connect_pseudoClient($adminserv->{'nickname'},$adminserv->{'identd'},$adminserv->{'host'},$adminserv->{'modos'},$adminserv->{'nickname'},$nadmin->{'numeric'},$adminserv->{'descripcion'});
  91. }
  92.  
  93. sub sendMsg
  94. {
  95.     my($channel,$plaintext) = (shift,shift);
  96.     print $socket qq($configuration->{'numeric'} P $channel :$plaintext\n);
  97. }
  98.  
  99.  
Coloreado en 0.005 segundos, usando GeSHi 1.0.8.4

PD: No quiero usar los módulos de Perl para IRC, quiero código nativo.
primitivo
Perlero nuevo
Perlero nuevo
 
Mensajes: 80
Registrado: 2013-03-22 23:05 @004

Publicidad

Re: bot IRC

Notapor explorer » 2015-04-19 22:17 @970

En principio, yo no veo nada raro, pero sí que hay un par de detalles que no me gustan.

Primero, el bucle infinito en el que creamos una nueva conexión del cliente, con IO::Socket::INET->new().

No sé, pero debería haber otra forma mucho más cómoda de mantener la conexión abierta.

Y segundo es el tema de los threads. Según el código, lo que haces es: crear un thread que ejecutará un trozo de código, para a continuación llamar a join(), que esperara a que termine ese proceso, para luego mandarle un kill().

Esto... ¿no lo estás complicando? Quiero decir: si yo mando ejecutar algo, supuestamente en otro núcleo del procesador, PERO me quedo esperando a que termine, ¿no es mejor hacer YO MISMO esa tarea?

Es decir, cambiar las líneas 36 a 49 por un simple $executeCommand->($tmpCommand,'Valor2');

Si dices que se atasca, lo que puedes hacer primero es saber dónde.

Al principio del programa pones un $| = 1; para que las salidas no usen la memoria temporal de salida, y luego colocas print() o say() en cada parte del código, para que vayas viendo la traza de la ejecución. Si en un momento dado se atasca, el último mensaje te dirá dónde está esperando.

En el libro Network Programming with Perl tienes ejemplos de cómo hacer clientes tanto con fork como con threads.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 17 invitados