Question

Étant donné que:
Le serveur est sur Windows XP sous ActiveState Perl
Le serveur est connecté à un réseau interne et à un réseau externe
Un ordinateur du réseau interne diffuse en udp vers 10.4.255.255 sur le port 9722

J'ai besoin de:
écouter la diffusion et transmettre les messages à une fonction

C'est le code que j'utilise:


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);
}

notez que & ampse; parseInput renvoie la chaîne d'origine à laquelle il a été transmis.

Mon problème:
après avoir appelé $ sock- > recv (), $ string devient vide. En utilisant une autre application, je constate que des informations sont sans aucun doute diffusées via 10.4.255.255, mais je ne peux pas y accéder.
Dans la mesure du possible, j'aimerais continuer à utiliser IO :: Socket :: INET.

edit: J'ai vérifié la valeur de retour de recv (..) et de $ !. il n'y a pas de valeur de retour de recv (..) et $! = 'Erreur inconnue'.

edit 2: j'essaie d'utiliser Socket; maintenant et avoir les éléments suivants:


$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: $!";


Il génère l'erreur - recv: erreur inconnue à ...

Était-ce utile?

La solution

Je pense avoir trouvé votre problème principal.

Le destinataire doit se connecter soit à une interface (INADDR_ANY), soit à l'adresse de diffusion du réseau (réseau unique ou réseau dirigé).

Voici un exemple de code pour l'expéditeur et le destinataire de la diffusion.

Lorsque vous utilisez setsockopt, faites attention! Vous devez emballer le dernier argument.

#!/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";
}

Autres conseils

Vérifiez la valeur de retour de $ sock- > recv et imprimez "$! \ n" . Quel type de message d'erreur est-il imprimé lorsque $ string devient vide? Vous devrez peut-être faire $ sock- > connect (...) ou $ sock- > bind (...) avant d'appeler $ sock- > recv () .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top