Tutorial :UDP Server listening to broadcast



Question:

Given that:
The server is on windows xp running ActiveState Perl
The server is connected to an internal network and an external network
A computer on the internal network is broadcasting in udp to 10.4.255.255 on port 9722

I need to:
listen to the broadcast and pass the messages to a function

This is the code I am using:

  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 &lt 20;$i++) {    my $string = 'a';    $sock->recv($string,1024);    print &parseInput($string);  }  

note that &parseInput returns the original string it was passed.

My problem:
after calling $sock->recv(), $string becomes empty. Using another application I can see that without a doubt there is information being broadcast across 10.4.255.255, but I cannot access it.
if at all possible, I would like to remain using IO::Socket::INET.

edit: I have checked the return value of recv(..) and $!. there is no return value from recv(..) and $! = 'Unknown Error'.

edit 2: I'm trying use Socket; now and have the following:

  $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: $!";  


It generates the error -- recv: Unknown error at ...


Solution:1

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";  }  


Solution:2

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().


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »