ブロードキャストをリッスンするUDPサーバー
-
03-07-2019 - |
質問
次のことを考えてください:
サーバーはActiveState Perl
を実行しているWindows XP上にあります
サーバーは内部ネットワークと外部ネットワークに接続されています
内部ネットワーク上のコンピューターは、ポート9722で10.4.255.255にudpでブロードキャストしています
する必要がある:
ブロードキャストを聞いて、メッセージを関数に渡します
これは私が使用しているコードです:
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);
}
&amp; parseInputは渡された元の文字列を返すことに注意してください。
私の問題:
$ sock-&gt; recv()を呼び出した後、$ stringは空になります。別のアプリケーションを使用すると、間違いなく10.4.255.255にブロードキャストされている情報があることがわかりますが、アクセスできません。
可能な限り、IO :: Socket :: INETを引き続き使用したいと思います。
edit: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:Unknown error at ...
解決
あなたが主な問題であることがわかったと思います。
受信者は、任意のインターフェイス(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";
}
他のヒント
$ sock-&gt; recv
の戻り値を確認し、 print&quot; $!\ n&quot;
を確認します。 $ string
が空になると、どのようなエラーメッセージが出力されますか? $ sock-を呼び出す前に、
。 $ sock-&gt; connect(...)
または $ sock-&gt; bind(...)
を実行する必要がある場合があります&gt; recv()