Hay algunos detalles que no quedan claros, como por ejemplo, en el servidor, no sabemos de dónde sale la variable $client_pub_key. Pero lo principal es que estamos enviando información que contiene caracteres de avance de línea, dentro de un protocolo entre servidor y cliente que precisamente usa los avance de línea para intercambiar comandos.
En la línea 6 del cliente estás enviando la firma, que es recogida, línea a línea, por el while() de la línea 6 del servidor. Te faltan las líneas de programa que vayan acumulando las líneas de la firma que vas recibiendo.
Aquí hay un ejemplo de lo que se puede hacer. Primero el servidor:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
my $sock = IO::Socket::INET->new(
LocalHost => 'localhost', # Opcional. Indicamos en dónde escuchamos
LocalPort => 1234, # Por dónde
Listen => 125, # Número de oyentes
Reuse => 1, # Admitir nuevas peticiones de forma simultánea
Proto => 'tcp', # Protocolo
) or die "Error creating socket: $!\n";
$|++; # No caché en pantalla (autoflush)
print "-- Server Program --\n";
while (my $cliente = $sock->accept() ) { # Esperamos conexiones
print "¡Conexión!\n";
$cliente->autoflush(1); # Opcional
my $key;
while (defined(my $line = <$cliente>)) { # Leemos por líneas
chomp $line;
print "Recibido: [$line]\n";
if ($line eq "Hello") { # Comienzo del protocolo
print $cliente "client connected\n"; # Respondemos
}
if ($line =~ m/-----BEGIN RSA PUBLIC KEY-----/i .. $line =~ m/-----END RSA PUBLIC KEY-----/i) {
$key .= "$line\n"; # es necesario un "\n" porque se lo hemos quitado antes
}
}
print "Fin de Conexión\n";
close $cliente;
chomp $key; # quitamos el último "\n" sobrante
print "Key: [$key]\n";
}
close($sock);
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
Arrancamos y quedamos esperando una conexión por parte del cliente. Cuando lo hace, leemos lo que nos manda, por líneas. Si nos manda una línea 'Hello', entonces respondemos con el mensaje de que estamos conectados. Si no, miramos a ver si la línea entra dentro del rango de una firma RSA, y si es así, la vamos agregando a $key. Finalmente, cuando el cliente corta la conexión, imprimimos la firma recibida.
Este es el cliente:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
my $socket = IO::Socket::INET->new(
PeerAddr => 'localhost', # A dónde hay que conectarse
PeerPort => 1234, # y en qué puerto
Proto => 'tcp', # y con qué protocolo
Timeout => 30, # tiempo máximo de espera de conexión
) or die "Error creating socket: $!\n";
my $key = '-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAsI016S2GsM4yJ7bDxvwlj1zaO5uP/SWfhoZQu5gKQ7be7zvpfJ/4
kqBRiN4WrCkr2KysE4MHa1Trnv0NFCLLAGuat+49sYyXosEUuJUfW13Xx/vhidxb
jb/BzpxPY6tVtEv72o6zDzzYPtWx6NiAPrdNWRHCTw/+onCm/NEafA+JZbZI+UKW
Iqv14786aohJFGfJTzrRG8kK5XAD944EPxERJk2R4JbZP/aGhvtnNb/vS7DKw86i
y1dsH/C4Yv6s+djOB2yY7H2DQtImmrUouE1a63Awt2dowbq5J/Xfn5+B1uqs2yff
PfrPsC2YogW3//Joi+f7fLRMQqWeSLWChQIDAQAB
-----END RSA PUBLIC KEY-----';
print "$key\n";
print $socket "Hello\n";
my $line = <$socket>;
chomp $line;
if ( $line eq "client connected" ) { # podemos comparar porque hemos quitado el "\n"
print $socket $key . "\n"; # agregamos "\n" porque la $key no lo tiene
}
$socket->close();
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
Es muy sencillo: nos conectamos al servidor, le mandamos el 'Hello', leemos la siguiente línea que nos responda, y si es lo acordado, le enviamos toda la $key.
Esta es otra variación, en la que modificamos el protocolo, para decirle al servidor exactamente cuántos bytes vamos a enviarle (la longitud de la firma).
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
my $sock = IO::Socket::INET->new(
LocalHost => 'localhost', # Opcional. Indicamos en dónde escuchamos
LocalPort => 1234, # Por dónde
Listen => 125, # Número de oyentes
Reuse => 1, # Admitir nuevas peticiones de forma simultánea
Proto => 'tcp', # Protocolo
) or die "Error creating socket: $!\n";
$|++; # No caché en pantalla (autoflush)
print "-- Server Program --\n";
while (my $cliente = $sock->accept() ) { # Esperamos conexiones
print "¡Conexión!\n";
$cliente->autoflush(1); # Opcional
my $key;
while (defined(my $line = <$cliente>)) { # Leemos por líneas
chomp $line;
print "Recibido: [$line]\n";
if ($line =~ /RSA(\d+)/) { # Cabecera del protocolo
my $n = read($cliente, $key, $1); # Leemos exactamente esa cantidad de bytes
print "Fin de Conexión. $n bytes leídos\n";
close $cliente; # y cerramos
print "Key: [$key]\n";
last;
}
}
}
close($sock);
Coloreado en 0.003 segundos, usando
GeSHi 1.0.8.4
El cliente también lo modificamos un poco:
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
my $socket = IO::Socket::INET->new(
PeerAddr => 'localhost', # A dónde hay que conectarse
PeerPort => 1234, # y en qué puerto
Proto => 'tcp', # y con qué protocolo
Timeout => 30, # tiempo máximo de espera de conexión
) or die "Error creating socket: $!\n";
my $key = '-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAsI016S2GsM4yJ7bDxvwlj1zaO5uP/SWfhoZQu5gKQ7be7zvpfJ/4
kqBRiN4WrCkr2KysE4MHa1Trnv0NFCLLAGuat+49sYyXosEUuJUfW13Xx/vhidxb
jb/BzpxPY6tVtEv72o6zDzzYPtWx6NiAPrdNWRHCTw/+onCm/NEafA+JZbZI+UKW
Iqv14786aohJFGfJTzrRG8kK5XAD944EPxERJk2R4JbZP/aGhvtnNb/vS7DKw86i
y1dsH/C4Yv6s+djOB2yY7H2DQtImmrUouE1a63Awt2dowbq5J/Xfn5+B1uqs2yff
PfrPsC2YogW3//Joi+f7fLRMQqWeSLWChQIDAQAB
-----END RSA PUBLIC KEY-----';
my $msg = 'RSA' . length $key;
print $socket "$msg\n$key"; # Mandamos cabecera y mensaje
$socket->close();
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
En definitiva, tú eres el que puede definir el protocolo a usar. Y según sea, necesitarás usar los "\n", o no.
Finalmente, esta es otra versión, con código superabreviado, cortesía del (monstruoso) módulo
IO::All
Using perl Syntax Highlighting
#!/usr/bin/perl
use 5.010;
use IO::All;
say '-- Server Program --';
my $socket = io(':1234')->fork->accept;
say '¡Conexión!';
my $header = $socket->getline;
if ($header =~ /RSA(\d+)/) { # Comienzo del protocolo
my $n = $socket->read($key, $1);
say "$n bytes leídos.";
say "Key: [$key]";
}
Coloreado en 0.002 segundos, usando
GeSHi 1.0.8.4
Using perl Syntax Highlighting
#!/usr/bin/perl
use IO::All;
my $io = io(':1234');
my $key = '-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAsI016S2GsM4yJ7bDxvwlj1zaO5uP/SWfhoZQu5gKQ7be7zvpfJ/4
kqBRiN4WrCkr2KysE4MHa1Trnv0NFCLLAGuat+49sYyXosEUuJUfW13Xx/vhidxb
jb/BzpxPY6tVtEv72o6zDzzYPtWx6NiAPrdNWRHCTw/+onCm/NEafA+JZbZI+UKW
Iqv14786aohJFGfJTzrRG8kK5XAD944EPxERJk2R4JbZP/aGhvtnNb/vS7DKw86i
y1dsH/C4Yv6s+djOB2yY7H2DQtImmrUouE1a63Awt2dowbq5J/Xfn5+B1uqs2yff
PfrPsC2YogW3//Joi+f7fLRMQqWeSLWChQIDAQAB
-----END RSA PUBLIC KEY-----';
my $msg = 'RSA' . length $key;
$io->print("$msg\n$key");
Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
En vez de usar print() y read(), se pueden usar las funciones send() y recv(), para tener mayor control sobre lo que se envía y recibe y cómo se envía y recibe.