• Publicidad

Comenzando con los sockets

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

Comenzando con los sockets

Notapor Warlox » 2011-01-29 07:33 @356

¡Hola!

Como especifiqué en un post anterior, soy un principiante en Perl, así que recurro a ustedes porque me surge una duda acerca de los sockets. Tengo los dos siguientes archivos:

server.pl
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use IO::Socket;
  4. use Net::hostent;
  5.  
  6. $servidor = IO::Socket::INET->new
  7. (
  8.         Proto => 'tcp',
  9.         LocalPort => '1717',
  10.         Listen => 5,
  11.         Reuse => 1
  12. );
  13.  
  14. die "No se pudo iniciar el servidor." unless $servidor;
  15. print "[Servidor \"",$0,"\" a la espera de clientes.]\n";
  16.  
  17. while($cliente = $servidor->accept())
  18. {
  19.         $cliente->autoflush(1);
  20.         print $cliente "Bienvenido a mi servidor.\n";
  21.        
  22.         $hostinfo = gethostbyaddr($cliente->peeraddr);
  23.        
  24.         printf "[Conectado con %s]\n", $hostinfo->name;
  25.         print $cliente "¿Algo que decir?";
  26.         close $cliente;
  27. }
  28.  
  29. close $servidor || die "close: $!";
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


cliente.pl
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. use Socket;
  4.  
  5. my ($remote,$port, $iaddr, $paddr, $proto, $line);
  6.  
  7. $remote  = 'localhost';
  8. $puerto    = 1717;
  9.  
  10. if ($puerto =~ /\D/)
  11. {
  12.         $puerto = getservbyname($puerto, 'tcp');
  13. }
  14. die "No se especificó un puerto." unless $puerto;
  15.  
  16. $iaddr   = inet_aton($remote) || die "No Host: $remote";
  17. $paddr   = sockaddr_in($puerto, $iaddr);
  18. $proto   = getprotobyname('tcp');
  19.  
  20. socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
  21. connect(SOCK, $paddr)    || die "connect: $!";
  22.  
  23. while (defined($line = <SOCK>))
  24. {
  25.         print $line;
  26. }
  27.  
  28. close (SOCK) || die "close: $!";
  29. exit;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Al ejecutar el servidor, me sale el siguiente texto en consola:
[Servidor "server.pl" a la espera de clientes.]


Cuando ejecuto el cliente (con el servidor abierto, obvio), me sale el siguiente texto en la consola del cliente:
Bienvenido a mi servidor.
¿Algo que decir?


Y en el servidor sale lo siguiente:
[Servidor "server.pl" a la espera de clientes.]
[Conectado con localhost.localdomain]


Ahora, mis dudas son:
1- ¿Porqué el servidor sigue abierto, y el cliente se cierra?
2- ¿Cómo hago para enviar instrucciones desde el cliente al servidor?

Espero me puedan ayudar :)
Saludos ^^
A veces hay que aprender a correr antes de caminar.
Avatar de Usuario
Warlox
Perlero nuevo
Perlero nuevo
 
Mensajes: 12
Registrado: 2011-01-29 04:23 @224
Ubicación: /home/warlox/

Publicidad

Re: Comenzando con los sockets

Notapor explorer » 2011-01-29 10:16 @469

Warlox escribiste:1- ¿Porqué el servidor sigue abierto, y el cliente se cierra?
La conexión con el cliente se cierra en la línea 26 del servidor. Y éste sigue abierto porque inicia un nuevo proceso de escucha en el while().

Warlox escribiste:2- ¿Cómo hago para enviar instrucciones desde el cliente al servidor?
Haces print() hacia el servidor usando el gestor de archivos que usaste para abrir el canal.

En este artículo de la Linux Journal de 1999 encontrarás todas las combinaciones, desde los servidores y clientes más sencillos hasta los más complicados. Eso sí, como se trata de un texto de hace doce años, ahora existen más módulos que permiten realizar ciertas tareas de forma más cómoda. Pero las bases están ahí. Y en el libro «Network Programming with Perl», de Lincoln D.Stein, Addison Wesley, 2000, ISBN 0-201-61571-1.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comenzando con los sockets

Notapor Warlox » 2011-01-29 13:11 @591

Vale, lo he modificado de la siguiente manera:

server.pl
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use IO::Socket;
  4. use Net::hostent;
  5.  
  6. $servidor = IO::Socket::INET->new
  7. (
  8.         Proto => 'tcp',
  9.         LocalPort => '1717',
  10.         Listen => 5,
  11.         Reuse => 1
  12. );
  13.  
  14. die "No se pudo iniciar el servidor." unless $servidor;
  15. print "[Servidor \"",$0,"\" a la espera de clientes.]\n";
  16.  
  17. while($cliente = $servidor->accept())
  18. {
  19.         $cliente->autoflush(1);
  20.         print $cliente "Bienvenido a mi servidor.\n";
  21.        
  22.         $hostinfo = gethostbyaddr($cliente->peeraddr);
  23.        
  24.         printf "[Conectado con %s]\n", $hostinfo->name;
  25.         print $cliente "Inserta un comando.";
  26.        
  27.         while(<$cliente>)
  28.         {
  29.                 next unless /\S/;
  30.                
  31.                 if(/salir/)
  32.                 {
  33.                         last;
  34.                 }
  35.                 elsif(/fecha/)
  36.                 {
  37.                         printf $cliente "La fecha es: %s\n", scalar localtime;
  38.                 }
  39.                 elsif(/cd/)
  40.                 {
  41.                         `eject`;
  42.                 }
  43.                 else
  44.                 {
  45.                         print $cliente "Comando desconocido\n";
  46.                 }
  47.         }
  48.         continue
  49.         {
  50.                 print $cliente "Inserta un comando.";
  51.         }
  52.                
  53.         close $cliente;
  54. }
  55.  
  56. close $servidor || die "close: $!";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


cliente.pl
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl -w
  2.  
  3. use Socket;
  4.  
  5. my ($remote,$port, $iaddr, $paddr, $proto, $line);
  6.  
  7. $remote  = 'localhost';
  8. $puerto    = 1717;
  9.  
  10. if ($puerto =~ /\D/)
  11. {
  12.         $puerto = getservbyname($puerto, 'tcp');
  13. }
  14. die "No se especificó un puerto." unless $puerto;
  15.  
  16. $iaddr   = inet_aton($remote) || die "No Host: $remote";
  17. $paddr   = sockaddr_in($puerto, $iaddr);
  18. $proto   = getprotobyname('tcp');
  19.  
  20. socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
  21. connect(SOCK, $paddr)    || die "connect: $!";
  22.  
  23. while (defined($line = <SOCK>))
  24. {
  25.         print $line;
  26. }
  27.  
  28. close (SOCK) || die "close: $!";
  29. exit;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Ejecutándolo desde dos terminales, el programa sí funciona, pero nunca llega al cliente.pl la línea "Inserta un comando.", por lo que el server.pl no recibe los comandos :S

Caso contrario, si inicio el server.pl en la terminal, y me conecto por telnet 127.0.0.1 1717, sí funciona a las 1000 maravillas.

¿A qué se debe?
A veces hay que aprender a correr antes de caminar.
Avatar de Usuario
Warlox
Perlero nuevo
Perlero nuevo
 
Mensajes: 12
Registrado: 2011-01-29 04:23 @224
Ubicación: /home/warlox/

Re: Comenzando con los sockets

Notapor explorer » 2011-01-29 13:19 @597

Es posible que el texto esté siendo almacenado por el caché de salida. Desactívalo colocando

$|++;

al principio del programa.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comenzando con lo sockets

Notapor Warlox » 2011-01-29 14:10 @632

Mira, he hecho el siguiente video para que me entiendas mejor, y veas exactamente cuál es mi duda o problema:

http://www.youtube.com/watch?v=qDo6EiC93Wc

Espero ansiosamente, me puedas ayudar :$
Saludos ^^
A veces hay que aprender a correr antes de caminar.
Avatar de Usuario
Warlox
Perlero nuevo
Perlero nuevo
 
Mensajes: 12
Registrado: 2011-01-29 04:23 @224
Ubicación: /home/warlox/

Re: Comenzando con lo sockets

Notapor explorer » 2011-01-29 14:17 @637

¿Has hecho lo que he dicho en el mensaje anterior, de desactivar la caché de salida?

Con el telnet sí que lo ves porque telnet no tiene caché de salida. La frase de petición del comando no sale porque no tiene un carácter de fin de línea al final, y por eso, esa frase queda en la caché de salida esperando a que a) el buffer se llene, o b) se reciba la petición de enviar un carácter de fin de línea.

Desactivando el caché de salida, se soluciona el problema.

Esta está comentado en otros hilos del foro. Te recomiendo que les mires. Usa el sistema de búsqueda para localizarles. Prueba a buscar por "sockets"
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comenzando con los sockets

Notapor Warlox » 2011-01-29 14:35 @649

De hecho, hice lo que me dijiste anteriormente, de desactivar la caché, primero lo coloqué en el cliente y no sirvió, luego lo coloqué en el servidor y tampoco sirvió :S
A veces hay que aprender a correr antes de caminar.
Avatar de Usuario
Warlox
Perlero nuevo
Perlero nuevo
 
Mensajes: 12
Registrado: 2011-01-29 04:23 @224
Ubicación: /home/warlox/

Re: Comenzando con lo sockets

Notapor explorer » 2011-01-29 15:26 @684

He hecho unas pruebas, y tienes razón. Aún sabiendo que el buffer de caché está desactivado por defecto, según se lee en la documentación de IO::Socket, no funciona como se espera.

Lo que me temo es que el origen del problema está en el uso de IO::Socket en la parte del servidor, y de Socket en la parte del cliente.

Prueba a programar servidor y cliente usando el mismo módulo IO::Socket.

Te recomiendo que mires el listado del servidor (Listing 5) y el cliente (Listing 6) del artículo que te enlacé antes en la Linux Journal, porque son unos ejemplos casi iguales a lo que quieres conseguir (dialogo de comandos entre cliente y servidor).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Comenzando con los sockets

Notapor Warlox » 2011-01-29 19:37 @859

¡Gracias! Ahora más tarde los leo, y cualquier duda te pregunto :)
Saludos ^^
A veces hay que aprender a correr antes de caminar.
Avatar de Usuario
Warlox
Perlero nuevo
Perlero nuevo
 
Mensajes: 12
Registrado: 2011-01-29 04:23 @224
Ubicación: /home/warlox/

Re: Comenzando con los sockets

Notapor Warlox » 2011-01-30 00:40 @070

¡No entiendo! :S
Tras leerlo muchas veces, no entiendo :S

A ver, si no es mucho pedir, ¿ustedes me podrían decir, más o menos, cómo hacer un "chat" en Perl?, o sea, algo super simple: yo abro el servidor, otra persona abre el cliente y nos mensajeamos por medio de la aplicación.

Me encantaría si me pudieran explicar más o menos cómo hacerlo :$
Saludos ^^
A veces hay que aprender a correr antes de caminar.
Avatar de Usuario
Warlox
Perlero nuevo
Perlero nuevo
 
Mensajes: 12
Registrado: 2011-01-29 04:23 @224
Ubicación: /home/warlox/

Siguiente

Volver a Básico

¿Quién está conectado?

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