3

鉴于:
服务器在运行 ActiveState Perl
的 windows xp 上 服务器连接到内部网络和外部网络
内部网络上的计算机正在通过 udp 广播到端口 9722 上的 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);
}

请注意 &parseInput 返回它传递的原始字符串。

我的问题:
调用 $sock->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: $!";


它会生成错误——recv: Unknown error at ...

4

2 回答 2

4

我相信我发现你是主要问题。

接收器必须绑定到任何接口( 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";
}
于 2009-05-07T12:49:03.257 回答
1

$sock->recv检查和的返回值print "$!\n"$string变空时会打印什么样的错误信息?您可能需要做$sock->connect(...)$sock->bind(...)打电话之前$sock->recv()

于 2009-05-01T22:07:14.710 回答