Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Checking if a socket has some data to read

by perlgsm (Initiate)
on Jun 13, 2013 at 16:17 UTC ( #1038790=perlquestion: print w/replies, xml ) Need Help??
perlgsm has asked for the wisdom of the Perl Monks concerning the following question:

Greetings experts,

I am using 'Net::SMPP' to have a transceiver SMPP connection(tcp) to exchange some SMSs.

The read_pdu() function offered by the library blocks until some data is available. In order to fix this I'm using IO::Select->can_read() to check if some data is available of the wire, so that I can execute the read_pdu to actually read the data.

The problem is can_read is always returning an undef, I tried many tricks and methods, but none have worked.

I'm attaching my code here.

#!/usr/bin/perl use IO::Socket; use IO::Select; use Data::Dumper; use Net::SMPP; #use warnings; $tt=time(); $host="some_ip"; $port=7661; $smpp = Net::SMPP->new_transceiver($host, port=>$port, system_id => 'test', password => 'test', system_type => 'smpp' # sadsadsdsdsasource_porty => 60001, ) or die; $port=`netstat -an|grep 7661`; #print "$port\n"; if($port=~/tcp\s+\d\s+\d\sxx\.xxx\.xx\.xx:(\d+)\s+xx\.xxx\.xx\.xx:7661 +.*ESTABLISHED/) { $pt=$1; } $lsn = new IO::Socket::INET(Listen => 2, LocalAddr =>'localhost',Local +Port => $pt); print "\nlistening on port : "; print $lsn->sockport(); print "\n"; $sel = new IO::Select( $lsn ) or die "cant bind"; print "count".$sel->count() or die "cant get count"; print "before while\n\n"; while(1) { print "here\n"; $results = $sel->can_read(0);# or die "cant read"; #print Dumper @results; print "\n****Outside if****"; print "results== $results\n"; if(@results!=undef) { print "\ninside if"; $pdu = $smpp->read_pdu(); $a=$pdu->{source_addr}; $b=$pdu->{destination_addr}; $msg=$pdu->{short_message}; $pay=$pdu->{message_payload}; print "Msg: $a->$b\t$msg\t$pay\n\n"; } else { print "hello"; print $sel->count(); } }

Any idea would be highly appreciated.

Many thanks, perlgsm

Replies are listed 'Best First'.
Re: Checking if a socket has some data to read
by 5mi11er (Deacon) on Jun 13, 2013 at 17:57 UTC
    You could start by reviewing this: Check network MTU size

    It uses code that I stole from Net::Ping and another node from here in the monastery, but definitely uses non-blocking calls, and does actually read some data "off the wire".


      Thanks Scott, for the script. but I seem to be doing it the same way, for I always get undef from can_read() even if there is some data available on the wire.
        Hmm, no, I think you're confusing can_read with the routine that actually does the reading, you're confusing a scalar variable with an array, and I can't tell if you've turned buffering off on the $lsn file handle, but I'm guessing not.

        Your code:

        $results = $sel->can_read(0);# or die "cant read"; #print Dumper @results; print "\n****Outside if****"; print "results== $results\n";

        Ping code:

        if ( $select -> can_read( 0 ) ) { my $remote = recv ( $pinger, $buff, SIZE, RCV_FLAGS ); if ( $debug ) { print "result from ", unpack("C*",$remote), ":", unpack ( "C*", $target_addr), "\n"; } # sometimes ICMP replies come from other devices, filter those out if ( $remote eq $target_addr ) { $received++; } }

        So, you've, at best, got a boolean result from the can_read, but then you use that as if can_read returned an array of data from the wire, rather than use a recv() call to actually read the data properly.

        I'm also betting that you're Suffering from Buffering, which means unless you've tested by sending tons of stuff, the buffer never filled up, and it *LOOKS* like you've not received anything.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1038790]
Approved by ww
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2018-05-25 17:31 GMT
Find Nodes?
    Voting Booth?