• Publicidad

Perl y Socket

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

Perl y Socket

Notapor jomarq » 2015-02-02 10:53 @495

Amigos Perlianos, tengo el siguiente código que es un servidor, mediante el cual me conecto a un cliente por medio de sockets:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use IO::Socket::INET;
  2.  
  3. # auto-flush on socket
  4. $| = 1;
  5.  
  6. # creating a listening socket
  7. my $socket = new IO::Socket::INET(
  8.     LocalHost => 'localhost',
  9.     LocalPort => '232',
  10.     Proto     => 'tcp',
  11.     Listen    => 1,
  12.     Reuse     => 1
  13. );
  14. die "No se puede crear el socket $!\n" unless $socket;
  15. print "El servidor a la espera de conexión en el puerto 232\n";
  16.  
  17. while (1) {
  18.  
  19.     # waiting for a new client connection
  20.     my $client_socket = $socket->accept();
  21.  
  22.     # get information about a newly connected client
  23.     my $client_address = $client_socket->peerhost();
  24.     my $client_port    = $client_socket->peerport();
  25.     print "Conexión desde $client_address:$client_port\n";
  26.  
  27.     # read up to 1024 characters from the connected client
  28.     my $data = "";
  29.     $client_socket->recv( $data, 1024 );
  30.     print "Datos recibidos: $data\n";
  31.  
  32.     # write response data to the connected client
  33.     $data = "ok";
  34.     $client_socket->send($data);
  35.  
  36.     # notify client that response has been sent
  37.     shutdown( $client_socket, 1 );
  38. }
  39.  
  40. $socket->close();
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


El tema es que sí tengo conexión, sí recibo datos, pero estos datos están incompletos. La cual es como la siguiente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
POST /SubmitReturn/01050945SKYA082 HTTP/1.1
Host: localhost:232
Connection: Keep-Alive
User-Agent: MC75/4.1
Content-Length: 723
Content-Type: application/json
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Incluso como se puede ver en el ítem "Longitud de contenido" me da un valor (723), pero solo muestra estos datos genéricos, no muestra contenido propio, el cual debería ser una serie de datos como velocidad, rumbo, etc. Por favor, recurro a ustedes para hacerme ver cuál es mi error. Gracias por su tiempo.

P.D.: He intentado cambiando el valor 1024 por un número mayor (2048, 4096), pero sin éxito alguno.

Jomarq
jomarq
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2015-01-13 12:31 @563

Publicidad

Re: Perl y Socket

Notapor explorer » 2015-02-02 12:36 @567

El problema está en que, al recibir un carácter de fin de línea, recv regresa para que el programa procese la línea recién recibida.

Es más cómodo usar el operador diamante:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use IO::Socket::INET;
  3.  
  4. # auto-flush on socket
  5. $| = 1;
  6.  
  7. my $port = 232;
  8.  
  9. # creating a listening socket
  10. my $socket = new IO::Socket::INET(
  11.     LocalHost => 'localhost',
  12.     LocalPort => $port,
  13.     Proto     => 'tcp',
  14.     Listen    => 1,
  15.     Reuse     => 1
  16. );
  17. die "No se puede crear el socket $!\n" unless $socket;
  18. print "El servidor a la espera de conexión en el puerto $port\n";
  19.  
  20. while (1) {
  21.  
  22.     # waiting for a new client connection
  23.     my $client_socket = $socket->accept();
  24.  
  25.     # get information about a newly connected client
  26.     my $client_address = $client_socket->peerhost();
  27.     my $client_port    = $client_socket->peerport();
  28.     print "Conexión desde $client_address:$client_port\n";
  29.  
  30.     # read up to 1024 characters from the connected client
  31.     my $data = "";
  32.     #$client_socket->recv( $data, 1024 );
  33.     while (<$client_socket>) {
  34.         $data .= $_;
  35.     }
  36.     print "Datos recibidos: $data\n";
  37.  
  38.     # write response data to the connected client
  39. #    $data = "ok";
  40. #    $client_socket->send($data);
  41.  
  42.     # notify client that response has been sent
  43. #    $client_socket->shutdown( 1 );
  44. }
  45.  
  46. $socket->close();
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
(sacado de aquí, parte del famoso artículo de programación en red en Perl)

Ahora bien, se puede hacer de varias formas. En el ejemplo que te he puesto, ves que vamos acumulando los datos que recibimos, hasta que el cliente *cierra* la conexión, y esa es la razón por la cual están comentadas las líneas que siguen, porque ya no tiene sentido enviar información a ese cliente.

Otra opción es la que se ve en los ejemplos enlazados: hay un bucle while() que va procesando cada línea, y responde al cliente según lo que haya enviado.

En cuanto a tu caso, tienes la ventaja de saber el tamaño del cuerpo del mensaje. Al leer esa línea, puedes tomar nota de esa cantidad, y al terminar la cabecera, después de la línea en blanco que sabes que separa el cuerpo, comenzar a leer esa cifra, en otro bucle, en donde vas reduciendo la cifra a medida de que vayas recibiendo datos. Algo así:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my $longitud = $content_length;  # cifra sacada de la cabecera
  2. my $datos;                       # acumulador
  3. while ($longitud > 0) {          # mientras tengamos cosas que leer
  4.     $client_socket->recv( $data, $longitud);
  5.     $datos .= $data;
  6.     $longitud = $content_length - length $datos;
  7. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Perl y Socket

Notapor jomarq » 2015-02-02 15:42 @696

Estimado explorer,

hice lo recomendado, pero mi perl queda en espera; solo arroja el mensaje (ningún otro dato adicional):
Conexión desde <Ip Cliente>:puerto

Y se queda ahí congelado, lo que sospecho es que mi perl (servidor) está esperando alguna respuesta del cliente, como un termino de conexión o algo así.

El cliente envía datos cada minuto, lo que este servidor perl tendría que hacer es leer cada nueva transmisión e imprimirla y luego quizá borrarla de ser el caso.
jomarq
Perlero nuevo
Perlero nuevo
 
Mensajes: 8
Registrado: 2015-01-13 12:31 @563

Re: Perl y Socket

Notapor explorer » 2015-02-02 15:51 @702

Yo arranco el programa y queda ahí esperando.

Desde otra terminal, hago un telnet localhost 232, y se conecta. Le envío algunos textos, y el servidor los replica. Luego meto el carácter de fin de transmisión y la corto, y el servidor vuelve a la espera.

Acuérdate de poner $| = 1, que lo quité para hacer una prueba.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
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 1 invitado