2009-04-30 9 views
2

を放送するためにリスニング:サーバーは、ActiveStateのPerlの
サーバは、内部ネットワークと外部ネットワークに接続されているを実行しているWindows XP上で

内部ネットワーク上のコンピュータは、UDPでの放送は10.4にありますポート上の.255.255 9722
UDPサーバーがあることを考えると

に私が必要:
が放送に耳を傾け、機能

にメッセージを渡す。これは、私が使用していたコードです:


my $sock; 

do { 
    eval { 
    $sock = IO::Socket::INET->new(LocalPort => 9722, Proto => 'udp') 
      or die("Couldn't open the socket: [email protected]"); 
    1; 
    }; 
    warn([email protected]) and sleep(5) if([email protected]); 
} while ([email protected]); 

for(my $i = 0;$i < 20;$i++) { 
    my $string = 'a'; 
    $sock->recv($string,1024); 
    print &parseInput($string); 
} 

注:& parseInputは、渡された元の文字列を返します。

私の問題:
$ sock-> recv()を呼び出した後、$ stringは空になります。別のアプリケーションを使用すると、間違いなく10.4.255.255にブロードキャストされている情報があることがわかりますが、アクセスできません。
可能であれば、IO :: Socket :: INETをそのまま使用したいと思います。

編集:私はrecv(..)と$!の戻り値をチェックしました。 recv(..)と$!の戻り値はありません。 = '不明なエラー'。

編集2:私はソケットを使用しようとしています。今、次があります


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


それがエラーを生成 - のrecv:

答えて

2

私はあなたが主な問題だと思っています。

レシーバは、任意のインターフェイス(INADDR_ANY)またはネットワークのブロードキャストアドレス(すべてのネットワークの1つまたは指向のもの)にバインドする必要があります。

ブロードキャスト送信者と受信者の両方のコード例です。

setsockoptを使用するときは注意してください!あなたは最後の引数をパックする必要があります。

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

ありがとう!私はブロードキャストアドレスにバインドしようとしましたが、私はあなたのコードに似ています。 – smskelley

+0

あなたは答えが好きで、それがあなたの問題を解決するように思えるなら、それをマークしてあなたの答えとして選ぶことができますか?ありがとう! –

1

...で不明なエラーが$sock->recv、およびprint "$!\n"の戻り値を確認してください。 $stringが空になると、どのようなエラーメッセージが表示されますか? $sock->recv()を呼び出す前に$sock->connect(...)または$sock->bind(...)を行う必要があります。

+0

データグラムソケットでなぜrecvが失敗するのか想像もつきませんが、戻り値を確実に確認してください。 – Bklyn

+0

私はrecv(..)と$!の戻り値をチェックしました。 recv(..)と$!の戻り値はありません。 = '不明なエラー'。 – smskelley

関連する問題