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

¿Fue útil?

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 () .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top