Servidor UDP escuchando la transmisión
-
03-07-2019 - |
Pregunta
Dado que:
El servidor está en Windows XP ejecutando ActiveState Perl
El servidor está conectado a una red interna y una red externa
Una computadora en la red interna está transmitiendo en udp al 10.4.255.255 en el puerto 9722
Necesito:
escuchar la transmisión y pasar los mensajes a una función
Este es el código que estoy usando:
my $sock;
do {
eval {
$sock = IO::Socket::INET->new(LocalPort => 9722, Proto => 'udp')
or die("Couldn't open the socket: $@");
1;
};
warn($@) and sleep(5) if($@);
} while ($@);
for(my $i = 0;$i < 20;$i++) {
my $string = 'a';
$sock->recv($string,1024);
print &parseInput($string);
}
tenga en cuenta que & amp; parseInput devuelve la cadena original que se pasó.
Mi problema:
después de llamar a $ sock- > recv (), $ cadena se vacía. Al usar otra aplicación puedo ver que, sin lugar a dudas, se está transmitiendo información a través de 10.4.255.255, pero no puedo acceder a ella.
Si es posible, me gustaría seguir usando IO :: Socket :: INET.
editar: he comprobado el valor de retorno de recv (..) y $ !. no hay valor de retorno de recv (..) y $! = 'Error desconocido'.
edición 2: Estoy tratando de usar Socket; ahora y tener lo siguiente:
$proto = getprotobyname('udp');
socket(SOCKET, PF_INET, SOCK_DGRAM, $proto) or die "socket: $!";
setsockopt(SOCKET, SOL_SOCKET, SO_BROADCAST, 1) or die "sockopt: $!";
bind(SOCKET, sockaddr_in(9722, inet_aton('192.168.0.103'))) or die "bind: $!";
recv(SOCKET, $msg, 128, 0) or die "recv: $!";
Genera el error - recv: error desconocido en ...
Solución
Creo que encontré tu problema principal.
El receptor debe vincularse a cualquier interfaz (INADDR_ANY) o a la dirección de transmisión de la red (ya sea a todas las redes o a la dirigida).
Aquí hay un código de ejemplo tanto para el emisor como para el receptor.
Al usar setsockopt ten cuidado! Tienes que empacar el último argumento.
#!/usr/bin/perl -w
# broadcast sender script
use strict;
use diagnostics;
use Socket;
my $sock;
my $receiverPort = 9722;
my $senderPort = 9721;
socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp')) || die "socket: $!";
setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!";
setsockopt($sock, SOL_SOCKET, SO_BROADCAST, pack("l", 1)) or die "sockopt: $!";
bind($sock, sockaddr_in($senderPort, inet_aton('192.168.2.103'))) || die "bind: $!";
while (1) {
my $datastring = `date`;
my $bytes = send($sock, $datastring, 0,
sockaddr_in($receiverPort, inet_aton('192.168.2.255')));
if (!defined($bytes)) {
print("$!\n");
} else {
print("sent $bytes bytes\n");
}
sleep(2);
}
#!/usr/bin/perl -w
# broadcast receiver script
use strict;
use diagnostics;
use Socket;
my $sock;
socket($sock, PF_INET, SOCK_DGRAM, getprotobyname('udp')) || die "socket: $!";
setsockopt($sock, SOL_SOCKET, SO_REUSEADDR, pack("l", 1)) || die "setsockopt: $!";
bind($sock, sockaddr_in(9722, inet_aton('192.168.2.255'))) || die "bind: $!";
# just loop forever listening for packets
while (1) {
my $datastring = '';
my $hispaddr = recv($sock, $datastring, 64, 0); # blocking recv
if (!defined($hispaddr)) {
print("recv failed: $!\n");
next;
}
print "$datastring";
}
Otros consejos
Verifique el valor de retorno de $ sock- > recv
, y imprima " $! \ n "
. ¿Qué tipo de mensaje de error se imprime cuando $ string
se queda vacío? Es posible que tenga que hacer $ sock- > connect (...)
o $ sock- > bind (...)
antes de llamar a $ sock- > recv ()
.