• Publicidad

Enviar y recibir información a través de IO::socket

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Enviar y recibir información a través de IO::socket

Notapor kondenado » 2006-08-22 18:18 @804

Bueno, tengo el siguiente problema, espero me puedan ayudar.

Estoy creando un script que se conecta a un puerto y recibe constantemente información del servidor. Hasta el momento puedo recibir la información y procesarla, pero también quiero enviar información aunque sin dejar de recibir.
Es algo así cómo un chat, estar esperando en todo momento la información (imprimiéndole en pantalla) y poder enviar en cualquier momento info hacia el server. La gracia es hacerlo en modo consola y con un solo script.

¿Será posible?
Avatar de Usuario
kondenado
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2006-08-21 18:57 @831

Publicidad

Notapor explorer » 2006-08-22 18:28 @811

Utilizando el sistema de búsqueda de este foro me han salido unos cuantos resultados.

Aquí hay uno interesante:
viewtopic.php?t=935
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

Notapor kondenado » 2006-08-23 18:43 @821

Tal vez me expliqué mal, eso no es lo que yo busco. Lo que necesito es un script al cual pueda enviar y recibir información paralelamente e ingresada por el usuario por <STDIN>, pero en el mismo script, algo así como:

Código: Seleccionar todo
información proveniente del server
información proveniente del server
información proveniente del server
write: información a enviar


Para entender mejor la analogía pensemos que quiero hacer un chat:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;
use IO::Socket;

my $sock = IO::Socket::INET->new( PeerAddr => "host.com",
                                                 Port => 1111,
                                                 Proto => 'tcp') || die "$!\n";

while (<$sock>)
          {
             print $_;
           }
# hast aki todo bien, pero al mismo tiempo ke el script esta
# recibiendo a todo momento la info proveniente del server, me gustaría
# saber si se puede tener un prompt para poder ir enviando
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Avatar de Usuario
kondenado
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2006-08-21 18:57 @831

Notapor explorer » 2006-08-23 19:38 @860

Yo aprendí leyendo esta página:
http://www.linuxjournal.com/article/3237

Aunque te recomiendo una lectura completa, lo que necesitas está a partir del ejemplo nº5, con un ejemplo de comunicación bidireccional entre servidor y cliente. Y ejemplos más adelante muestran cómo enviar comandos desde el cliente al servidor leyéndolos desde la entrada estándar.
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

Notapor kondenado » 2006-08-26 19:06 @837

He leído el paper (muy bueno por cierto) pero no he encontrado solución a lo que busco. Lo explicaré de la siguiente manera:

Servidor:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;
use IO::Socket;

my($sock, $accept, $count);

$sock = IO::Socket::INET->new( LocalPort => 10001,
                               Proto => 'tcp',
                               Listen => 6,
                               Reuse => 1) || die "Socket problem $!\n";

if ($sock)
    {
     $accept = $sock->accept();
     while ($accept)
            {
              sleep 2;
              print $accept "Hola $count\n";
              $count++;
              if ($count == 5)
                  {
                    shutdown($accept,2);
                    exit(1);
                  }
            }
       }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Cliente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;
use IO::Socket;

my($sock, $in, $msg);

$sock = IO::Socket::INET->new( PeerAddr => "127.0.0.1",
                               PeerPort => 10001,
                               Proto => 'tcp') || die "Socket problem $!\n";

while ($in = <$sock>)
       {
         print $in;
         print "write: ";
         chomp ($msg = <STDIN>);
         print $sock $msg;
        }

shutdown($sock,2);
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Este código funciona de lo más bien, pero... al momento de conectar el cliente al servidor, recibirá la info mandada por el server ("Hola $count"), lo que en teoría debería llegar al cliente cada dos segundos. Con el cliente recibimos la info y después el script nos pregunta por info para mandar al server, pero si no introducimos info en <STDIN>, la info del server no nos llegará incluso si pasan un millón de segundos, ya que el script está a la espera de info ingresada por el user. Por lo tanto, mi objetivo es saber si hay alguna manera de evitar eso, imprimiendo la info en pantalla cada dos segundos sin importar si el cliente ha ingresado o no la info.
Avatar de Usuario
kondenado
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2006-08-21 18:57 @831

Notapor explorer » 2006-08-26 20:49 @909

La respuesta entonces es haciendo un fork() en el lado del cliente. Un hilo se encargará de hablar con el server, y el otro de hablar con el usuario.
En el mismo enlace, en el ejemplo nº7 (A forking Client), lo tienes.
Última edición por explorer el 2009-05-27 06:59 @333, editado 1 vez en total
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

Notapor AkonD » 2006-08-27 07:47 @366

Lo puedes hacer de 3 maneras

1- Usando fork() (lo cual creara un subproceso por cada cliente)
2- Usando IO::Select;
3- Usando thread;

Yo te recomiendo que uses IO::Select

Un simple ejemplo de IO::Select i sockets.. (sacado de Google)

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
   use IO::Select;
   use IO::Socket;

    $lsn = new IO::Socket::INET(Listen => 1, LocalPort => 8080);
    $sel = new IO::Select( $lsn );
   
    while(@ready = $sel->can_read) {
        foreach $fh (@ready) {
            if($fh == $lsn) {
                # Create a new socket
                $new = $lsn->accept;
                $sel->add($new);
            }
            else {
                # Process socket

                # Maybe we have finished with the socket
                $sel->remove($fh);
                $fh->close;
            }
        }
    }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


salu2
AkonD
Perlero nuevo
Perlero nuevo
 
Mensajes: 50
Registrado: 2005-10-06 06:36 @316
Ubicación: España

Notapor explorer » 2006-08-27 09:57 @456

AkonD, el ejemplo que has puesto está sacado de la página de manual de IO::Select, y se refiere a cómo hacer un server que crea nuevos sockets.
En cambio, lo que kondenado pedía era del lado del cliente, para atender tanto lo que le llega desde el servidor como del usuario.
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

Notapor AkonD » 2006-08-27 14:56 @664

Cierto, sorry no lei el post entero, le dejo un ejemplo rapido :P
Código: Seleccionar todo
my $select = IO::Select->new($socket,\*STDIN);
while (my @ready = $select->can_read) {
  foreach (@ready) {
    if ($_ eq \*STDIN) {
      lectura_stdin(\*STDIN);
    } else {
      lectura_socket($_);
    }
  }
}


salu2
AkonD
Perlero nuevo
Perlero nuevo
 
Mensajes: 50
Registrado: 2005-10-06 06:36 @316
Ubicación: España

Notapor kondenado » 2006-08-27 17:18 @762

He probado el uso de fork y me ha funcionado :D , ya kon anterioridad había usado fork, pero no tenía idea ke kon el ejemplo explikado en akel paper podía lograr lo ke buskaba.

Por cierto, no he entendido el ejemplo ke dio AkonD:

AkonD escribiste:Cierto, sorry no lei el post entero, le dejo un ejemplo rapido :P
Código: Seleccionar todo
my $select = IO::Select->new($socket,\*STDIN);
while (my @ready = $select->can_read) {
  foreach (@ready) {
    if ($_ eq \*STDIN) {
      lectura_stdin(\*STDIN);
    } else {
      lectura_socket($_);
    }
  }
}


salu2
Perl programming
Avatar de Usuario
kondenado
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2006-08-21 18:57 @831

Siguiente

Volver a Intermedio

¿Quién está conectado?

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

cron