views:

1393

answers:

2
+1  A: 

Check the return value of $sock->recv, and print "$!\n". What kind of error message does it print when $string becomes empty? You may have to do $sock->connect(...) or $sock->bind(...) before calling $sock->recv().

pts
Definitely check your return values, though its hard to conceive of why recv on a datagram socket would fail.
Bklyn
I have checked the return value of recv(..) and $!. there is no return value from recv(..) and $! = 'Unknown Error'.
roamn
+1  A: 

I believe I found you're main problem.

The receiver has to bind either to any interface ( INADDR_ANY ) or to the network's broadcast address ( either the all networks one or the directed one ).

Here is example code for both the broadcast sender and receiver.

When using setsockopt watch out! You have to pack the last argument.

#!/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";
}
Robert S. Barnes
thanks! though I tried binding to the broadcast address, I'll try something more closely resembling your code to ensure mine is right.
roamn
If you like the answer and it seems to solve your problem could you mark it up and select it as your answer? Thanks!
Robert S. Barnes