scuzzy has asked for the wisdom of the Perl Monks concerning the following question:

ok guys, I thought flushing the buffer would help, apparently not. I'm using select as a sort of timeout for data on an incomming socket. The scenario goes like this. I've got a socket waiting for data, if it's there enterpret it, if however, no data has been recieved within 30 seconds, check the status of the line with a pseudo ping to make sure the host on the other side is listening. Here's the problem, when the aplication starts, it never times out, ONLY when I press return on the kb does it start to time out. I'm thinking it's because for SOME reason, the socket wasn't updated and it's still waiting for data on it, wich wasn't the case.
my $selectFD; $selectFD = new IO::Select($rec[$RXThreadNumber], undef, undef, 1); $|++; # flush the buffer apparently... while(@bits = $selectFD->can_read) { select(undef, undef, undef, 0.1); foreach $fdThread (@bits) { if($fdThread == $rec[$RXThreadNumber]) { print("Fetching pdu\n"); # the following if is to make sure that the only time we try + fetch an sms # is when there is actual sms activity on the socket... and +nothing else... # this was causing problems before because a sock kill init +was creating# noise on the line and the aplication was trying to ent +erperet this as # a PDU... if($pdu = $rec[$RXThreadNumber]->read_pdu()) { print("CMD: $pdu->{cmd}\n"); print("STATUS: $pdu->{status}\n"); print("SERTYPE: $pdu->{service_type}\n"); print("SEQ: $pdu->{seq}\n"); print("SOURCE: $pdu->{source_addr}\n"); print("DESTINATION: $pdu->{destination_addr}\n"); #print("DATA: $pdu->{data}\n"); print("MESSAGE: $pdu->{short_message}\n"); $test = $rec[$RXThreadNumber]->deliver_sm_resp(seq=>$pd +u->{seq}, message_id=>''); my $nowRXTime = genTime(); my $queryRX = $tdbh->prepare("insert into MOHits values +(NULL, NULL, \"$pdu->{source_addr}\", \"$nowRXTime\", \"$pdu->{short_ +message}\", 0, \"$pdu->{destination_addr}\")"); $queryRX->execute; print("Fetched pdu\n"); } } if((time() - $startTime) > 5) { $startTime = time(); print("Enquiring link...\n"); if($rec[$RXThreadNumber]->enquire_link()) { print("Link is fine...\n"); } else { print("Link is DOWN! Bringing up again...\n"); $rec[$RXThreadNumber] = Net::SMPP-new_receiver( $tshost, smpp_version => $smppVer, system_id => $tssysid, password => $tspassword, system_type => $tssystype, dest_addr_ton => 0x91, # Type Of Number, +this means its "2783XXXXXXX" dest_addr_npi => 0x00, addr_ton => 0x91, addr_npi => 0x00, source_addr_ton => 0x91, source_addr_npi => 0x00, port => $tsport ) or warn("can't connect to smsc: $!\n"); } } } }
The timeout ONLY fires when I press return on the kb once the aplication starts.... any idea's? Thanks Scuzz. (;

Replies are listed 'Best First'.
Re: SELECT help...
by integral (Hermit) on Feb 18, 2003 at 09:29 UTC
    $selectFD = new IO::Select($rec[$RXThreadNumber], undef, undef, 1);
    The immediate problem I can see with your code is the above call. The constructor for IO::Select doesn't take the same parameters as the select function. It takes a list of handles. Check the IO::Select pod for more information. This means that your timeout isn't begin set properly, and you experience the symptoms of this.
    $|++; # flush the buffer apparently...
    If you want to know more about how this works, you need to read the perlvar pod. If you use the IO::Handle classes for your filehandles you can use their autoflush method to make this nicer.

    --
    integral, resident of freenode's #perl
    
Re: SELECT help...
by castaway (Parson) on Feb 18, 2003 at 10:46 UTC
    .. And the other problem is that 'can_read()' waits indefinitely for data. If you want it to wait 30 seconds and then give up, you need to call it: can_read(30)
    At the moment you're only comparing the time if data actually comes through - if its only doing that when you press the keyboard, I assume you've added 'STDIN' to the sockets in the IO::Select object.

    C.

Re: SELECT help...
by Thelonius (Priest) on Feb 18, 2003 at 13:10 UTC
    One problem with your code is that you have a typo: Net::SMPP-new_receiver instead of Net::SMPP->new_receiver. You should always "use strict;" which will catch that error.

    Not knowing the complete context for your problem, I think that you want something like this:

    my $channel = $rec[$RXThreadNumber]; my $select = IO::Select->new($channel); my $timeout=30; while ($channel) { my @ready = $select->can_read($timeout); if (@ready) { # If you add more sockets to select object, # this code will need to change if($pdu = $channel->read_pdu()) { print("Fetching pdu\n"); processpdu($pdu, $RXThreadNumber); } else { # eof or error on socket # you can do something like this: $select->remove($channel); $channel->close(); # Now, do you want to try to reconnect? If so, something # like this: if ($channel = TryReconnect($RXThreadNumber)) { $select->add($channel); } } } else { # Time-out print("Enquiring link...\n"); if($rec[$RXThreadNumber]->enquire_link()) { print("Link is fine...\n"); } else { print("Link is DOWN! Bringing up again...\n"); $select->remove($channel); $channel->close(); if ($channel = TryReconnect($RXThreadNumber)) { $select->add($channel); } } } } # We exit loop if we are no longer connected sub TryReconnect { my ($threadnum) = @_; $rec[$threadnum] = Net::SMPP->new_receiver( $tshost, smpp_version => $smppVer, system_id => $tssysid, password => $tspassword, system_type => $tssystype, dest_addr_ton => 0x91, dest_addr_npi => 0x00, addr_ton => 0x91, addr_npi => 0x00, source_addr_ton => 0x91, source_addr_npi => 0x00, port => $tsport ) or warn("can't connect to smsc: $!\n"); }
Re: SELECT help...
by crouchingpenguin (Priest) on Feb 18, 2003 at 12:46 UTC

    I think you want to check out

    perldoc -f alarm

    "Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic."