Frage

Da:
Der Server ist unter Windows XP Activestate Perl
Der Server ist mit einem internen Netzwerk und einem externen Netzwerk verbunden
Ein Computer im internen Netzwerk ist Rundfunk in udp zu 10.4.255.255 auf Port 9722

Ich muss:
hören Sie die Sendung und übergeben Sie die Nachrichten an eine Funktion

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 gibt die ursprüngliche Zeichenkette, die es übergeben wurde.

Mein Problem:
nach Socken- $ Aufruf> recv (), wird $ string leer. mit einer anderen Anwendung kann ich sehen, dass über 10.4.255.255 ohne Zweifel werden ausgestrahlt dort Informationen, aber ich kann nicht darauf zugreifen.
wenn überhaupt möglich, würde Ich mag IO :: INET :: Socket bleiben verwenden.

edit: Ich habe den Rückgabewert von recv geprüft (..) und $ !. gibt es keinen Rückgabewert von recv (..) und $! = 'Unbekannter Fehler'.

bearbeiten 2: Ich use Socket versucht; jetzt und haben folgende Möglichkeiten:


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


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

War es hilfreich?

Lösung

Ich glaube, ich fand Sie Hauptproblem sind.

Der Empfänger entweder an jeder Schnittstelle (INADDR_ANY) oder an die Netzwerk-Broadcast-Adresse (entweder die alle Netze eine oder die darauf gerichtet, eines) zu binden.

Hier ist Beispielcode sowohl für den Broadcast-Sender und Empfänger.

Bei der Verwendung von setsockopt passt! Sie haben das letzte Argument zu 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";
}

Andere Tipps

Überprüfen Sie den Rückgabewert von $sock->recv und print "$!\n". Welche Art von Fehlermeldung druckt es, wenn $string leer wird? Sie können zu tun haben $sock->connect(...) oder $sock->bind(...) vor $sock->recv() aufrufen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top