2009-04-30 153 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)或網絡的廣播地址(無論是所有網絡還是定向網絡)。

以下是廣播發送者和接收者的示例代碼。

使用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

檢查的$sock->recv,並print "$!\n"返回值。當$string變空時,它會打印什麼樣的錯誤信息?在致電$sock->recv()之前,您可能必須執行$sock->connect(...)$sock->bind(...)

+0

絕對檢查你的返回值,儘管很難想象爲什麼在數據報套接字上recv會失敗。 – Bklyn 2009-05-02 03:50:59

+0

我檢查了recv(..)和$!的返回值。沒有從recv(..)和$!的返回值! ='未知錯誤'。 – smskelley 2009-05-06 14:56:22