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

Notapor explorer » 2007-11-27 05:30 @271

El problema es el siguiente: un servidor web 'normal' espera recibir una cadena de texto terminada en un retorno de carro; y tu, lo que envías es un string con partes en binario y NO envías el carácter de final de línea, por lo que el servidor web no responderá porque todavía no ha terminado de recibir el mensaje completo.

Si en la línea del @a agregas al final el valor 10 (carácter de nueva línea) entonces sí que responderá el servidor web:

Con el siguiente programa:
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 || 'w3desa01';
my $port = shift || 80;
my $sock = new IO::Socket::INET(
    PeerAddr => $host,
    PeerPort => $port,
    Proto    => 'tcp'
)
 || die "socket error :  $!/n"
;
$sock->autoflush(1);


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, 10
  );


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

#  while ($sock) {
    print "RESPONSE:", <$sock>, "\n/RESPONSE\n\n";
#  }
}

__END__
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
obtenemos la siguiente salida:
Código: Seleccionar todo
$ ./kk.pl
Enviando...
RESPONSE:HTTP/1.1 400 Bad Request
Date: Tue, 27 Nov 2007 10:17:52 GMT
Server: Apache/1.3.33 (Win32) mod_perl/1.29_01-dev mod_ssl/2.8.22 OpenSSL/0.9.7f PHP/4.3.9
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<HTML><HEAD>
<TITLE>400 Bad Request</TITLE>
</HEAD><BODY>
<H1>Bad Request</H1>
Your browser sent a request that this server could not understand.<P>
The request line contained invalid characters following the protocol string.<P>
<P>
<HR>
<ADDRESS>Apache/1.3.33 Server at w3desa01 Port 80</ADDRESS>
</BODY></HTML>

/RESPONSE

Es decir, el servidor web sí que ha respondido porque ha recibido una carácter de fin de línea. Lo malo es que no sabe responder al galimatías que le hemos mandado.

Como he dicho antes, todo depende del protocolo.

En un mensaje anterior has dicho que desde el programa del jefe se sabe que se ha recibido correctamente y que éste ha respondido.

Lo que pasa es que, seguramente, el mensaje del jefe no manda un carácter de final de línea como que el operador <$sock> está esperando. Y por eso se queda ahí, esperando ese carácter que nunca llega.

Debes hacer una de estas dos cosas: si el mensaje de respuesta del jefe es de un tamaño fijo, usa la función read(). Si el mensaje no es de tamaño fijo, deberás leerlo de otra manera. Por ejemplo, con getc():

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  while (defined ($_ = getc $sock)) {
    print $_;
  }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Con estas líneas puedo leer todos los bytes que me van llegando, hasta que el servidor corta la conexión. Les saco a pantalla, pero podría guardarles en un buffer, escribir a un fichero, etc.

Lo he probado con el mismo servidor web y he obtenido la misma salida de antes (lógico, porque el servidor web sí que me manda caracteres de final de línea).
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

Publicidad

Notapor rklz » 2007-11-27 23:05 @003

Bueno, resulta que estoy probando las cosas desde mi casa en Windows, mediante PuTTY conectado a los servidores de la empresa , probando 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($_);
    }

     while (defined ($_ = getc $sock)) {
    print $_;
  }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


la salida textual es :

®§PuTTYPuTTY

:| jajajaja es muuuuy raro xD

PD: Agregando el 10 al final de los bytes, probando contra la página web funcioná bien :)


EDIT :
Agregando la función ord() en esta:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
    while (defined ($_ = getc $sock)) {
    print ord($_);
  }
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


parte del código, obtuve el resultado que quería (creo :P): una cadena de bytes, que me falta corroborar para ver si es la correcta, pero creería que sí. Muchas gracias a todos por las ayudas :)

PD2 : Explorer, una preguntita, ¿qué es la variable $|++, que definiste al principio de tu programa?
Avatar de Usuario
rklz
Perlero nuevo
Perlero nuevo
 
Mensajes: 38
Registrado: 2007-05-25 13:28 @603
Ubicación: Rosario, Argentina

Notapor explorer » 2007-11-28 04:04 @211

El necesitar ord() o no depende de lo que quieras hacer después con la información recibida.

$| es una variable especial. Está descrita en perlvar. Es el autoflush para la salida estándar.
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

Anterior

Volver a Intermedio

¿Quién está conectado?

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