Página 1 de 1

Captura de datos en variables en conexión TCP

NotaPublicado: 2013-03-07 15:44 @697
por willbender
Buen día. Tengo este inconveniente:

Tengo un socket server que envía un mensaje hacia un servidor que lo interpreta y devuelve otro mensaje de respuesta separando los campos por un enter (\n). Mi problema es que dependiendo de lo que devuelva el mensaje puede variar en tamaño, es decir, pueden venir "n" campos por consiguiente debo capturar cada dato en una variable diferente para luego yo interpretar dichos datos por ejemplo yo envío este mensaje.

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
02170213NEM0|WS|VI|B|JRSYS|asdf5asdf5asdf5asdf5                    |1411|1234|012||02281515|151520||00000000|151520|0100|003000|123456|123456|88888888|320|01|000|0|000000000|4568270128290512|00000000|000000011234|0|0|0|0|
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y al responder el servidor me devuelve esto, por ejemplo, si el mensaje fuera negativo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
0
-32
TRANSMICION DUPLICADA
0.00
BU
94 TRANSACCION YA EXISTE (NUMERO REFERENCIA)
807424
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y esto por ejemplo si el mensaje fuera positivo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1
807424
APROBADA

201411
        0.00
3456
    17929.55
     1802.19
    17929.55
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Como verán, dependiendo de si es válido o no válido cambia la longitud del mensaje de respuesta.

Yo lo que necesito es imprimirlo en un archivo de registro que llevo de esta manera:

printf log_file "[$campo1|$campo2|$campo3|$campo4|$campo......|$campox]";

de donde las variables son

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
 1                = $campo1
807424            = $campo2
APROBADA          = $campo3
               
201411            = $campo4
        0.00      = $campo5
3456              = $campo6
    17929.55      = $campo7
     1802.19      = $campo8
    17929.55      = $campo9
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Hasta el momento llevo esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub EnviaMensaje {
  2.  
  3.     my $mensaje  = shift;
  4.     my $puerto   = shift;
  5.  
  6.     $socketCliente = new IO::Socket::INET (
  7.             PeerHost => "$IP",
  8.             PeerPort => "$puerto",
  9.             Proto => 'tcp',
  10.                 ) or die "ERROR in Socket Creation : $!\n";
  11.  
  12.     print $socketCliente "$mensaje\n";
  13.  
  14.     while (defined($respuesta = <$socketCliente>)) {
  15.         chop $respuesta;
  16.         @retorno = split("/\n/",$respuesta);
  17.         if ( $respuesta eq "" ) {
  18.             next;
  19.         }
  20.         printf log_file "RECEIVE:$respuesta\n";
  21.     }
  22.  
  23. }
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


y me responde esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
RECEIVE: 00880
RECEIVE: -32
RECEIVE: TRANSMICION DUPLICADA
RECEIVE: 0.00
RECEIVE: BU
RECEIVE: 94 TRANSACCION YA EXISTE (NUMERO REFERENCIA)
RECEIVE: 807424
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


¿Me podrían ayudar, por favor? ¡Gracias, muy amables!

Re: Captura de datos en variables en conexión TCP

NotaPublicado: 2013-03-07 19:06 @837
por explorer
Primero, una pregunta: ¿los corchetes que has puesto en las respuestas ([]), realmente, no te los manda, verdad? Solo manda el texto que está entre los corchetes, ¿verdad? Si es así, es mejor que vuelvas a editar tu mensaje y los quites.

Viendo el programa, también me queda una duda: ¿el servidor corta la conexión cuando ha terminado de enviar la respuesta? Si no es así, ¿cómo sabes que ha terminado de enviar una respuesta? Lo digo porque tienes puesto un bucle while() que va leyendo todo lo que le llega, hasta que corta la comunicación y termina (bueno, ahora no me acuerdo del comportamiento de los sockets y lo que devuelven).

La línea 16 no sirve para nada, ya que no haces uso del contenido de @retorno en ningún otro sitio. Y $respuesta tampoco es modificada.

Lo que realmente sucede es que estás recibiendo un conjunto de líneas, y el bucle while() se ejecuta por cada una de ellas. Esa es la razón de que te salga una línea RECEIVE por cada una de las líneas recibidas.

En el caso (fácil) de que el servidor corte la conexión, o (también fácil) el servidor envíe un carácter corchete de final (cosa que no debe ser porque en tu programa no los tienes en cuenta), entonces sí que sabemos cuándo un mensaje ha terminado de llegar. Y entonces podemos cambiar el programa para que vayamos guardando las líneas en un array, por ejemplo @campos, y cuando se termina de recibir todo, imprimimos todos los campos juntos. Algo así (no probado):

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.     my @campos;
  2.  
  3.     while (defined(my $respuesta = <$socketCliente>)) {
  4.         chop $respuesta;
  5.         next if $respuesta eq "";
  6.  
  7.         push @campos, $respuesta;                           # guardamos la $respuesta dentro de @campos
  8.     }
  9.  
  10.     printf log_file '[', join('|', @campos), "]\n";   # sacamos todos los @campos unidos (join) por '|'
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Re: Captura de datos en variables en conexión TCP

NotaPublicado: 2013-03-08 10:51 @493
por willbender
Sí, disculpa, los ([]) no van. Sí, el servidor al terminar la conexión corta la comunicación.

Y gracias, haré el test y te comento. ¡Muy amable!