• Publicidad

Socket problema con las respuestas

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

Socket problema con las respuestas

Notapor rklz » 2007-11-22 13:20 @597

Saludos, les cuento mi problema...
Tengo el siguiente código....

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#/usr/bin/perl -w

use strict;
use IO::Socket;

my @a;
my ($espera, $data, $response, $new_sock, $buf, $leng);
my $host = shift || 'x.x.x.x';
my $port = shift || x;
my $sock = new IO::Socket::INET(
                   PeerAddr => $host,
                   PeerPort => $port,
                   Proto    => 'tcp'
            )
         || die "socket error :  $!/n"
         ;

if ($sock) {
    while (1) {
        comando();
        $espera = getc(STDIN);
    }
}

sub comando {
    @a = ( 1,  59, 160,   1,   1,  1, 160,   1,   1,  20,  49,  46,  50,  98,  44,  77,
         111, 118, 105, 115, 116, 97, 114,  44, 105, 110, 116, 101, 114, 110, 101, 116,
          46, 103, 112, 114, 115, 46, 117, 110, 105, 102, 111, 110,  46,  99, 111, 109,
          46,  97, 114,  44, 119, 97, 112,  44, 119,  97, 112,   0,  34,   3
    );

    foreach (@a) {
        print $sock chr($_);
    }

    print scalar $sock;
}
Coloreado en 0.011 segundos, usando GeSHi 1.0.8.4


La idea es que el cliente éste manda esa secuencia de bytes a un programa que le responde, pero la respuesta jamás llega :( ..

¿Alguna idea?
Avatar de Usuario
rklz
Perlero nuevo
Perlero nuevo
 
Mensajes: 38
Registrado: 2007-05-25 13:28 @603
Ubicación: Rosario, Argentina

Publicidad

Re: Socket problema con las respuestas

Notapor Jenda » 2007-11-22 16:58 @749

No intentas leer ninguna respuesta.

rklz escribiste:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    print scalar $sock;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



debe ser

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    print scalar <$sock>;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



Es posible que haya otros problemas, no lo he testado.

Jenda
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa

Notapor rklz » 2007-11-22 18:30 @812

Ya había probado de esa forma y nada tampoco :(
Avatar de Usuario
rklz
Perlero nuevo
Perlero nuevo
 
Mensajes: 38
Registrado: 2007-05-25 13:28 @603
Ubicación: Rosario, Argentina

El código me parece OK, ¿qué tal lo que mandas?

Notapor Jenda » 2007-11-23 11:35 @524

Si pruebo el código con localhost y port 80, yo obtengo:

Código: Seleccionar todo
    HTTP/1.1 400 Bad Request


Es exactamente lo que esperaba. ¿Sabes, por cierto, si lo que mandas es correcto y completo? ¿No debe estar acabado por un \n o algo así?
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa

Notapor creating021 » 2007-11-23 15:59 @708

La idea es que el cliente éste manda esa secuencia de bytes a un programa que le responde, pero la respuesta jamás llega :( ...


¿Cómo estás esperando la respuesta? En ninguna parte de ese código está escuchando al servidor.

Si realmente crees que el servidor es el que no escucha, trata de usar la función send (de IO::Socket, lee los manuales) aunque creo que el problema está en el cliente.
Expect the worst, is it the least you can do?
Avatar de Usuario
creating021
Perlero frecuente
Perlero frecuente
 
Mensajes: 595
Registrado: 2006-02-23 16:17 @720
Ubicación: Frente al monitor

Notapor explorer » 2007-11-23 16:39 @735

Quizás pasa lo que dice Jenda: que el servidor no sabe cuándo ha terminado de recibirlo todo...

Si yo creo un servidor que esté preparado para recibir bloques de 62 bytes (el tamaño del array @a) entonces sí que funciona:

servidor:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -w
use strict;
use IO::Socket;

my $sock = new IO::Socket::INET(
                   LocalHost => 'localhost',
                   LocalPort => 7890,
                   Proto     => 'tcp',
                   Listen    => SOMAXCONN,
                   Reuse     => 1);
$sock or die "no socket :$!";
STDOUT->autoflush(1);
my($new_sock, $buf);
while ($new_sock = $sock->accept()) {
    read $new_sock, $buf, 62;
    print ord($_)," " foreach split //, $buf;
    print "\n";
    print $new_sock "ENVIADO!\n";
    close $new_sock;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

cliente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -w
use strict;
use IO::Socket;

my $sock = new IO::Socket::INET(
                  PeerAddr => 'localhost',
                  PeerPort => 7890,
                  Proto    => 'tcp');
$sock or die "no socket :$!";

my @a = (  1,  59, 160,   1,   1,  1, 160,   1,   1,  20,  49,  46,  50,  98,  44,  77,
         111, 118, 105, 115, 116, 97, 114,  44, 105, 110, 116, 101, 114, 110, 101, 116,
          46, 103, 112, 114, 115, 46, 117, 110, 105, 102, 111, 110,  46,  99, 111, 109,
          46,  97, 114,  44, 119, 97, 112,  44, 119,  97, 112,   0,  34,   3
);

print "Enviando ", scalar @a, " elementos\n";
foreach (@a) {
    print $sock chr($_);
}

print scalar <$sock>; # Respuesta del servidor

close $sock;
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
Arrancamos el servidor en una terminal, y el cliente en otra. En la del servidor aparecen la ristra de bytes y queda esperando para la siguiente. En la del cliente, aparece el indicativo de que sí han sido enviados y recibidos por el servidor. Pero esto lo podemos hacer porque el servidor sabe exáctamente que tiene que leer solo 62 bytes antes de continuar con el programa. No está contemplado otro caso, como por ejemplo que la longitud sea distinta o que la comunicación se corte a la mitad.

Viendo la lista de bytes, se nota que hay muchas minúsculas, así que se trata de un texto, junto con otros valores en binario. De todos los valores, el que me llama la atención es el segundo: está indicando la longitud de los datos que le siguen.

Supongamos que el protocolo es ese: el bloque de datos comienza con un 1 y le sigue un byte que indica lo que le sigue. El servidor sabe entonces cuánta información debe leer.

Con este nuevo servidor:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -w
use strict;
use IO::Socket;

my $sock = new IO::Socket::INET(
                   LocalHost => 'localhost',
                   LocalPort => 7890,
                   Proto     => 'tcp',
                   Listen    => SOMAXCONN,
                   Reuse     => 1);
$sock or die "no socket :$!";
STDOUT->autoflush(1);
my($new_sock, $buf);

while ($new_sock = $sock->accept()) {

    $buf = getc $new_sock;              # Leemos el primer byte

    if ( $buf eq "\1" ) {
        print "Recibido inicio de paquete\n";

        my $longitud = 1 + ord getc $new_sock;  # Esperar la llegada de la longitud
        print "Recibiendo $longitud bytes\n";

        read $new_sock, $buf, $longitud;        # Leemos esa cantidad

        my ($h1,$h2,$texto,$crc)                # Desempaquetado
            = unpack("H8 H8 Z* H4", $buf);

        print "$h1,$h2\n";
        print "Texto:$texto.\n";
        print "$crc\n";
        print $new_sock "ENVIADO!\n";
    }
}
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4
y ahora el nuevo cliente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -w
use strict;
use IO::Socket;

my $sock = new IO::Socket::INET(
                  PeerAddr => 'localhost',
                  PeerPort => 7890,
                  Proto    => 'tcp');
$sock or die "no socket :$!";

my $texto = '1.2b,Movistar,internet.gprs.unifon.com.ar,wap,wap';

print $sock "\1";                               # Cabecera
print $sock chr(length($texto)+1+8+2-1);        # uno menos
print $sock chr $_ foreach ( 0xa0, 0x01, 0x01, 0x01, 0xa0, 0x01, 0x01, 0x14 );     # 8
print $sock "$texto\0";                         # 50
print $sock chr 0x22, chr 0x03;                 # 2

print scalar <$sock>; # Respuesta del servidor

close $sock;
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
obtenemos la misma respuesta, pero ahora el servidor ya está preparado para recibir otros textos con distinta longitud, y el cliente está modificado para ser fácil enviar otros textos.

Notar la facilidad de unpack en el servidor. Queda como ejercicio hacer lo mismo en la parte del cliente, para dejarlo incluso más sencillo.

(Movistar, ¿eh? :-) )

Imprescindible ver la página de Linux Journal sobre Networking.
Última edición por explorer el 2008-06-21 16:25 @726, 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 rklz » 2007-11-26 14:02 @626

Gracias a los 2 por tomarse el tiempo y revisar mi código , les cuento lo siguiente:

jenda dice que con este código:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#/usr/bin/perl -w

use strict;
use IO::Socket;

my @a;
my ($espera, $data, $response, $new_sock, $buf, $leng);
my $host = shift || 'x.x.x.x';
my $port = shift || x;
my $sock = new IO::Socket::INET(
                   PeerAddr => $host,
                   PeerPort => $port,
                   Proto    => 'tcp'
            )
         || die "socket error :  $!/n"
         ;

if ($sock) {
    while (1) {
        comando();
        $espera = getc(STDIN);
    }
}

sub comando {
    @a = ( 1,  59, 160,   1,   1,  1, 160,   1,   1,  20,  49,  46,  50,  98,  44,  77,
         111, 118, 105, 115, 116, 97, 114,  44, 105, 110, 116, 101, 114, 110, 101, 116,
          46, 103, 112, 114, 115, 46, 117, 110, 105, 102, 111, 110,  46,  99, 111, 109,
          46,  97, 114,  44, 119, 97, 112,  44, 119,  97, 112,   0,  34,   3
    );

    foreach (@a) {
        print $sock chr($_);
    }

    print scalar <$sock>;
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


obtiene una respuesta del servidor HTTP, pero yo intento lanzar el código contra un servidor HTTP que está corriendo y funcionando, y me pasa lo mismo: conecta, pero no obtengo ninguna respuesta :( , no sé qué es lo que estará pasando...

Y gracias explorer por revisar el post y armar esos códigos, pero te cuento que el servidor, no lo hago yo, el servidor lo tiene hecho mi jefe, en .net sobre Windows XP y teóricamente con solamente mandar esa cadena de bytes devuelve la respuesta; es por eso que no entiendo por qué nunca me llega, o por lo menos no se vuelca en la pantalla.

Otra de las cosas es que hicimos pruebas con mi jefe y pudimos ver que a él le llega correctamente la cadena de bytes, y me manda la respuesta, no hay error hasta ahí, entonces el problema está en mi código, pero no sé por qué :(

¡Ayuda!
Avatar de Usuario
rklz
Perlero nuevo
Perlero nuevo
 
Mensajes: 38
Registrado: 2007-05-25 13:28 @603
Ubicación: Rosario, Argentina

Notapor Jenda » 2007-11-26 17:27 @769

Este
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  #/usr/bin/perl -w
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

debe ser
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  #!/usr/bin/perl -w
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Cómo es la respuesta? ¿Tiene más líneas? Prueba a cambiar el último print a

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
print "RESPONSE\n", <$sock>, "\n/RESPONSE\n\n";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Jenda
Perlero nuevo
Perlero nuevo
 
Mensajes: 132
Registrado: 2007-10-29 06:31 @313
Ubicación: Praga, Republica Checa

Notapor explorer » 2007-11-26 18:14 @801

¿Y no será que sí que recibes la respuesta pero como no tiene un retorno de carro el programa no sabe que ha terminado de llegar?

¿Cómo es la respuesta? ¿De un tamaño fijo? En ese caso usa read.

Activa el autoflush.

No me importa cómo sea el programa servidor del jefe. Lo importante es saber perfectamente el protocolo. De ahí, lo que queda es que los dos programas se comporten bien.
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 rklz » 2007-11-26 20:38 @901

Pruebo con este código :

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl -w

use strict;
use IO::Socket;

STDOUT->autoflush(1);


my @a;
my ($espera, $data, $response, $new_sock, $buf, $leng);
my $host = shift || 'x.x.x.x';
my $port = shift || x;
my $sock = new IO::Socket::INET(
                   PeerAddr => $host,
                   PeerPort => $port,
                   Proto    => 'tcp'
            )
         || die "socket error :  $!/n"
         ;

if ($sock) {
    while (1) {
        comando();
#        $espera = getc(STDIN);
    }
}

sub comando {
    @a = ( 1,  59, 160,   1,   1,  1, 160,   1,   1,  20,  49,  46,  50,  98,  44,  77,
         111, 118, 105, 115, 116, 97, 114,  44, 105, 110, 116, 101, 114, 110, 101, 116,
          46, 103, 112, 114, 115, 46, 117, 110, 105, 102, 111, 110,  46,  99, 111, 109,
          46,  97, 114,  44, 119, 97, 112,  44, 119,  97, 112,   0,  34,   3
    );

    foreach (@a) {
        print $sock chr($_);
    }

    print "RESPONSE\n", <$sock>, "\n/RESPONSE\n\n";
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


y nadaaaa :(

Tiene que haber algún tipo de error, porque lo estoy usando contra el servidor de una página web, obviamente puerto 80, que está funcionando, y con telnet responde, pero el programa sigue haciendo lo mismo, se ejecuta y queda ahí, nunca se ve nada en pantalla ni se aborta inesperadamente, ¡¡¡simplemente se queda ahí!!!
Avatar de Usuario
rklz
Perlero nuevo
Perlero nuevo
 
Mensajes: 38
Registrado: 2007-05-25 13:28 @603
Ubicación: Rosario, Argentina

Siguiente

Volver a Intermedio

¿Quién está conectado?

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