• Publicidad

Comunicación Sockets

¿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.

Re: Comunicación Sockets

Notapor RastaCat » 2012-05-10 20:16 @886

Aquí os adjunto los paquetes Conex.pm y ConexCli.pm.

Me costo sudor y esfuerzo encontrar la solución, hasta que reestructure el código del todo. Espero que os pueda servir.

¡Buenas noches!
Adjuntos
ConexCli.pl
Por favor, renombrar archivo a ConexCli.pm
(1.42 KiB) 111 veces
Conex.pl
Por favor, renombrar archivo a Conex.pm
(1.65 KiB) 118 veces
RastaCat
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-10-27 04:08 @214
Ubicación: Tarragona

Publicidad

Re: Comunicación Sockets

Notapor explorer » 2012-05-10 21:26 @935

RastaCat escribiste:En primer lugar, informar que ya me funciona el servidor-cliente, y ya envía un mensaje al servidor, pero se cierra automáticamente. He hecho algunas pruebas más, y al intentar enviar un mensaje desde el servidor, los dos se quedan bloqueados (enviar mensaje tanto cliente como servidor...). He pensado en incorporar hilos en mi código, para que sea una ejecución independiente tanto como para recibir mensajes como para enviarlos.
A ver... si se trata de una serie de intercambios de información entre cliente y servidor, si los dos conocen el protocolo, no deberían bloquearse. El bloqueo es porque el que espera información, está esperando más de la que le envía el otro.

Repasa la lista de códigos de ejemplo que hay en el artículo enlazado: hay varias combinaciones de cliente/servidor, desde aquellos que solo se intercambian una línea de información, hasta la más compleja usando hilos.

En concreto, el listado 1 es el de un servidor que queda esperando la entrada de clientes, y cuando se conecta uno, le envía una línea, y cierra, esperando al siguiente cliente. El listado 2 es el cliente que acompaña ese tipo de servidor. Pero a partir de ahí, salta a usar el IO::Socket, porque es más cómodo (los programas se hacen más cortos).


RastaCat escribiste:Tengo una duda al obtener el nombre del host. Es curioso porque sólo me detecta el nombre del host si pongo el loopback (127.0.0.1), y no la IP privada de mi red (192.168...). ¿Esto es porque debo modificar el archivo hosts de mi ordenador y añadir esa IP? Si es así, ¿deberé añadir todas las direcciones IP, de los ordenadores que quiero que se quieran conectar a mi server con su IP pública?
Es el sistema operativo el que se encarga de hacer ese tipo de traducciones. El archivo /etc/nsswitch.conf es el que indica el orden de quién hace la traducción. Por ejemplo, en uno de mis servidores pone:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
hosts:          files dns
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4
Eso quiere decir que a la hora de conocer la IP de una máquina a partir de su nombre, primero mirará en el archivo /etc/hosts, y si de ahí no saca nada, preguntará al servidor DNS.

Sí que te resuelve el localhost porque estará definido en /etc/hosts.

En el programa, es la llamada inet_aton() la que solicita al sistema operativo la traducción de un nombre a dirección IP (cuatro bytes empaquetados). Si no es capaz de hacerlo, devuelve undef.

A mí sí que me funciona con las direcciones IP:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.10;
  3. use Socket;
  4.  
  5. my $iaddr = inet_aton("192.168.1.1");
  6.  
  7. say unpack "N", $iaddr;   # 3232235777
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4

Algo estará mal en el programa, que no lo haga de esta manera...
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: Comunicación Sockets

Notapor RastaCat » 2012-05-29 10:39 @485

Buenas tardes,

Tengo otra duda con respecto al servidor. He integrado la librería GTK y he hecho el chat con interfaz gráfica, y el problema me sigue igual: no me imprime los mensajes del cliente al servidor, solo me los imprime cuando cierro el socket.

¿Hay alguna forma para avisarle al servidor que he terminado de enviarle datos? ¿Algún tipo de EOF o algo por el estilo? ¿O simplemente pasarle el tamaño del "string" para que sepa que solo quiero enviarle la cadena? Por ejemplo: "Esto es una prueba".

También he intentado que el servidor sea NON-BLOCKING, con las siguientes líneas:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $flags = fcntl(SERVER, F_GETFL, 0)
  2.         or die "Can't get flags for socket: $!\n";
  3.  
  4. fcntl(SERVER, F_SETFL, $flags | O_NONBLOCK)  
  5.         or die "Can't make socket nonblocking: $!\n";
  6.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Pero al ejecutarlo con el Fnctl me sale el siguiente error:

Use of uninitialized value in subroutine entry at /usr/lib/perl5/Socket.pm line 405.
Thread 1 terminated abnormally: Bad arg length for Socket::unpack_sockaddr_in, length is 0, should be 16 at /usr/lib/perl5/Socket.pm line 405.


Y sí, el hacer el socket con las funciones: socket(), bind(), listen()... forma parte del proyecto... ¡je,je,je!, ¡ahora ya es una cuestión personal!

Os colgaré el código para que podáis probarlo.

P.D.: En cada código, hay una línea que sigue así: use lib (/home/..../Xat/Conexio) esta ruta debe indicar donde tenéis guardado los ficheros Finestra.pl ConexCli.pm, Conex.pm, clienteX.pm, serverX.pm (Ya os lo he dejado preparado). También añado un script llamado obreX donde abrirá las ventanas de servidor y cliente; este script debe de estar en la misma carpeta que el fichero Finestra.pl.

P.D.2.: Cambiar las extensiones de .txt a .pm, excepto Finestra.pl
Adjuntos
XAT.tar
(30 KiB) 122 veces
RastaCat
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-10-27 04:08 @214
Ubicación: Tarragona

Re: Comunicación Sockets

Notapor RastaCat » 2012-05-29 12:12 @550

Buenas,

Comentaros que ya tengo la solución.

Indagando por Internet he encontrado unas sentencias para enviar y recibir mensajes, añadiendo el tamaño máximo del mensaje. Son las funciones sysread(FILEHAND,SCALAR,LENGTH) y syswrite(FILEHAND,SCALAR,LENGTH).

Simplemente he sustituido lo que tenía en las funciones de recibir mensajes y enviar (repDada y enviarDada) por las respectivas funciones.

Así se pueden enviar datos, y el servidor los recibe sin ningún problema, y al instante.

Aún me queda retocar el servidor para que también pueda comunicarse con el cliente, ya que ahora mismo, es solo el cliente que puede interactuar con el servidor. Ya os avisaré cuando lo tenga.

P.D.: ¡Espero que esto sirva de ayuda a otras personas!

¡Saludos!

RastaCat.
RastaCat
Perlero nuevo
Perlero nuevo
 
Mensajes: 16
Registrado: 2010-10-27 04:08 @214
Ubicación: Tarragona

Anterior

Volver a Intermedio

¿Quién está conectado?

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

cron