鉴于:
服务器在运行ActiveState Perl的Windows XP上
服务器连接到内部网络和外部网络
内部网络上的计算机通过端口9722上的udp广播到10.4.255.255
我需要:
收听广播并将消息传递给函数
这是我正在使用的代码:
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。
编辑:我已经检查了recv(..)和$!的返回值。 recv(..)和$没有返回值! ='未知错误'。
编辑2:我正在尝试使用Socket;现在有以下几点:
$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: $!";
它会在......
答案 0 :(得分:2)
我相信我发现你是主要问题。
接收方必须绑定到任何接口(INADDR_ANY)或网络的广播地址(所有网络或指向的网络)。
以下是广播发送者和接收者的示例代码。
使用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";
}
答案 1 :(得分:1)
检查$sock->recv
和print "$!\n"
的返回值。当$string
变空时,它会打印什么样的错误消息?在致电$sock->connect(...)
之前,您可能需要$sock->bind(...)
或$sock->recv()
。