Problem with Perl networking on Windows XP

Posted on 2010-11-24
Last Modified: 2012-05-10
I have been trying to make the following code work without success. TIt is a simple thread waiting on a UDP port. There are lots of possible devices that may send packets to the port which are then simply placed in a file (not included here). I have verified that the UDP socket is created (netstat -a) and that the servver is sending packets. I ran a Windows program on the same UDP and it worked okay.

I am running on Strawberry perl, v 5.12. I am having two problems.

The first is that the can_read never fires except for timeouts. If I take it out, the recv blocks and never completes. As noted above, the sending is working and the port is open. I print out the handles in the function and the one I added is present. I also found that if I give a timeout = 0, can_read returns immediately and the whole routine loops rapidly. The documenation says a value of 0 results in a blocking call.

The second is that when I set $thread_stop (to kill the thread), Perl crashes when I execute the return. The routine I use to kill the thread, sets thread_stop and then does a join on the thread. I am using Visual Studio as my editor and it gets invoked with a runtime exception.

Can someone please look at the following code and tell me what I have done wrong? It looks fine to me and I have been fighting it for days. Thanks

sub listen_thread {

    $udp_sock = IO::Socket::INET->new(PeerAddr  => inet_ntoa(INADDR_BROADCAST),
                                      Proto     => udp,
                                      LocalPort => 48888)
      or die "socket: $@";
     my $s = new IO::Select($udp_sock);
     print "listen thread running\n";
     #make sure the handle is registered
    @ready = $s->handles();
    print "handles = \n";
    foreach $r (@ready)
           print "han: $r\n";

#enter loop to receive packets
    while (1)
        @ready = $s->can_read(5);
        print "waiting handles\n";
        foreach $r (@ready)
           print "rd $r\n";
        #see if we should terminate the thread
        if ($thread_stop == 1)
          print "listen thread terminated\n";
          return 1;
        # see if something is waiting
        print "th - $ready[0] - $udp_sock\n";      
        if ($ready[0] == $udp_sock)
          print "th-r-wait\n";
          $t = $udp_sock->recv($newmsg, 1400,0);
          print "th-r-done $t\n";
           print "listen thread timeout\n";
Question by:bob0206
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2

Accepted Solution

group0 earned 250 total points
ID: 34918854
Is there a special reason you're trying to bind the listening socket to a remote peer address of INADDR_BROADCAST?  If you just want to listen on a single UDP port for messages and then record them, here's a version that should do what you want (IO:Select is overkill in this case):

use strict;
use threads;
use threads::shared;
use IO::Socket::INET;

our $thread_stop : shared;

sub listen_thread {
	my %socket_params;
	$socket_params{'Proto'} = 'udp';
	$socket_params{'LocalPort'} = 48888;
	$socket_params{'Timeout'} = 5;
	my $sock = IO::Socket::INET->new(%socket_params) or die("unable to open socket: $@");

	print "listening thread started\n";
	while (1) {
		my ($buffer, $socket_error);
		my ($rin, $rout, $ein, $eout) = ('', '', '', '');
		vec($rin, fileno($sock), 1) = 1;
		if (select($rout=$rin, undef, $eout=$ein, $socket_params{'Timeout'})) {
			$sock->recv($buffer, 1500);
			if ($buffer) {
				printf("received message from %s:%u - %s\n", $sock->peerhost, $sock->peerport, $buffer); 
		} else {
			print "select() timeout\n";
			if ($thread_stop) {
				print "listening thread shutting down\n";
				return 1;

my $thr = threads->create('listen_thread');
$thread_stop = 1;
print "all done\n";

Open in new window

Here's a tiny sender to test with:

use strict;
use IO::Socket;
my $response = IO::Socket::INET->new(Proto=>'udp', PeerHost=>'',  PeerPort=>48888);
$response->send('sample udp message');

Open in new window

And here's the output:

listening thread started
select() timeout
select() timeout
received message from - sample udp message
select() timeout
select() timeout
select() timeout
select() timeout
listening thread shutting down
all done

Open in new window


Expert Comment

ID: 35118386
Any update?

Expert Comment

by:Suhas .
ID: 37313535
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Is there a file descriptor created for logfile using by logmsg within Perl script 4 145
Perl efficient DB Call 8 102
Control Number of Log Files -Perl 7 102
perl syntax 3 54
Email validation in proper way is  very important validation required in any web pages. This code is self explainable except that Regular Expression which I used for pattern matching. I originally published as a thread on my website : http://www…
A year or so back I was asked to have a play with MongoDB; within half an hour I had downloaded (,  installed and started the daemon, and had a console window open. After an hour or two of playing at the command …
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

732 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question