3 Stimmen

UDP Server hört auf Broadcast

Angesichts dessen:
Der Server läuft unter Windows xp mit ActiveState Perl
Der Server ist mit einem internen und einem externen Netz verbunden.
Ein Computer im internen Netz sendet in udp an 10.4.255.255 auf Port 9722

Ich muss es tun:
den Rundfunk abhören und die Nachrichten an eine Funktion weitergeben

Dies ist der Code, den ich verwende:

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

Beachten Sie, dass &parseInput die ursprüngliche Zeichenkette zurückgibt, die ihm übergeben wurde.

Mein Problem:
nach dem Aufruf von $sock->recv() wird $string leer. Mit einer anderen Anwendung kann ich sehen, dass zweifelsohne Informationen über 10.4.255.255 gesendet werden, aber ich kann nicht darauf zugreifen.
wenn möglich, möchte ich weiterhin IO::Socket::INET verwenden.

edit: Ich habe den Rückgabewert von recv(..) und $! überprüft. Es gibt keinen Rückgabewert von recv(..) und $! = 'Unknown Error'.

edit 2: Ich versuche jetzt Socket; zu verwenden und habe das folgende:

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

Es erzeugt den Fehler -- recv: Unbekannter Fehler bei ...

4voto

Robert S. Barnes Punkte 38141

Ich glaube, ich habe Ihr Hauptproblem gefunden.

Der Empfänger muss sich entweder an eine beliebige Schnittstelle ( INADDR_ANY ) oder an die Broadcast-Adresse des Netzes ( entweder die Adresse aller Netze oder die gerichtete Adresse ) binden.

Hier ist ein Beispielcode für den Sender und den Empfänger der Sendung.

Bei der Verwendung von setsockopt ist Vorsicht geboten! Sie müssen das letzte Argument packen.

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

1voto

pts Punkte 70857

Prüfen Sie den Rückgabewert von $sock->recv y print "$!\n" . Welche Art von Fehlermeldung wird ausgegeben, wenn $string leer wird? Sie müssen vielleicht Folgendes tun $sock->connect(...) o $sock->bind(...) vor dem Aufruf $sock->recv() .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X