Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

select() - How does it work?

Status
Not open for further replies.

fagga

Programmer
Jun 26, 2002
28
DE
Hi there,







I'm searching for information about the select()-funktion in perl for weeks but I couldn't find anything except the manpage but there is really not enough information about select().



My question is: How can I find out if I can read from a filehandle or a socket wich select() watches?



Here is my code:

Code:
while(1)

{

  vec($rin,fileno(READSOCKET),1) = 1;

  $ein = $rin;



  ($nfound, $timeleft) = select($rin, undef, $ein, 0);



  if($nfound)

  {

    $input = '';

    do

    {

      read(READSOCKET, $puffer, 1);

      print $puffer;

    }while(!($input =~ /<BR>/));

  } elsif(!$nfound)

  {

    print &quot;nothing happened\n&quot;;

  }

}

close(READSOCKET);



It seems to me that $nfound is always true, even if there is nothing to read on READSOCKET. So how do I know if I can read from READSOCKET?



Thank you very much for your answers.
 
All checking $nfound tells you is that one or more of your descriptors hit. It doesn't tell you which ones...you have to check $rin and $ein for that. Try this

while(1)
{
vec($rin,fileno(READSOCKET),1) = 1;
$ein = $rin;

# Since you're calling select with a timeout of 0, you
# don't really need the $timeleft, and can just call select
# in scalar context
$nfound = select($rin, undef, $ein, 0);


if ($nfound) {
if ( vec($rin,fileno(READSOCKET),1) ) {
# your read stuff here
} elsif ( vec($ein,fileno(READSOCKET),1) {
# your exception handling here
} else {
# Error here. $nfound set, but no descriptors
}
} else {
# Normal return from select, with no descriptors set
# This block will happen a lot since you have timeout
# set to zero
}
}
# You're also missing a way out of the loop, just FYI :)
close(READSOCKET);
 
Thank you very, very much. You seem to be the only person who can help me. :)



But I fear it still doesn't work. You said, $nfound should be negative in many cases because I set the timeout to 0. That's what I expected, but $nfound is *always* positive, so it blocks while reading and reading and reading... from the socket.



Now the critical part of my script looks like this:

Code:
while(1)

{

  vec($rin,fileno(READSOCKET),1) = 1;

  $ein = $rin;



  $nfound = select($rin, undef, $ein, 0);



  # I'm not sure what $ein stands for, but I think I don't need it, so I cut one if.

  if( $nfound && vec($rin,fileno(READSOCKET),1) )

  {

    # there is something to read

  } else

  {

    # there is nothing to read

  }

}

close(READSOCKET);



That's it. And it always keeps falling in the reading-part, so there seems to be always something to read on the socket? Or what's going on there?
 
Forget my last posting. The problem was my read-loop. It seems to block. Sorry.
 
You may not need $ein, but if you don't want to test the results for $ein, you should also remove it from the select() call. Just change the $ein to an undef, and get rid of the $ein = $rin during initialization.

Another thing to look at... if your select says there's something to read, but the read returns no data, then it usually means that your socket was closed from the other end. At least on my Tru64 UNIX system, that's the way it works...and it wasn't real well documented, either. :)

good luck
Richard
 
Thank you again for your help. But I found that my programm can go without select().
But that doesn't mean this thread is wasted. I think I'll need select() in the future, so I'm very glad to know how I have to use it now.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top