Article 12178 of comp.lang.perl:
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!pipex!howland.reston.ans.net!cs.utexas.edu!csc.ti.com!tilde.csc.ti.com!cauldron!ra.csc.ti.com!enterprise!sunds
From:
[email protected] (David M. Sundstrom)
Subject: Re: How to find if there's something on a Sock
Message-ID: <
[email protected]>
Sender:
[email protected]
Nntp-Posting-Host: enterprise.asic.sc.ti.com
Reply-To:
[email protected]
Organization: Texas Instruments
References: <
[email protected]>
Date: Thu, 31 Mar 1994 23:00:48 GMT
Lines: 83
In article
[email protected],
[email protected] (Andrew Smallbone) writes:
>
> Can anyone tell me how to find if there is something to read on a
> socket?
>
> I've been looking at:
> select(RBITS,WBITS,EBITS,TIMEOUT)
> and &FD_ISSET() - from /usr/include/sys/types.h
>
> But I can't figure out how to create the structures correctly? Any Ideas?
>
> I've got a socket that I both read and (occasionally) write too and
> want to check when a message has been received without waiting on a
> read() until something comes in. The messages haven't got newlines in
> so I can't do:
> while (<Socket>) {
> # process message code
> };
>
Assuming your socket filehandle is called "SOCK", then:
vec($rin,fileno(SOCKET),1) = 1;
select($rout=$rin, undef, undef, $Timeout);
$len=sysread(SOCKET,$buf,$buflen);
will block until something is there, unless you timeout. You
can use a timeout of zero to check without blocking. Use a timeout
of undef to wait forever.
The cool thing about select is that you can wait on more than
one thing, include other filehandles like STDIN:
vec($rin1,fileno(SOCK1),1) = 1;
vec($rin2,fileno(SOCK2),1) = 1;
$rin = $rin1 | $rin2;
for (;;) {
select($rout=$rin, undef, undef, undef);
if (vec($rout,fileno(SOCK1),1)) {
### do SOCK1 things
}
if (vec($rout,fileno(SOCK2),1)) {
### do SOCK2 things
}
}
Unbuffering your filehandles prior to using select will likely
be required:
select((select(SOCK), $|=1)[$[]);
Which may be more clearly written as:
local($savehandle)=select(SOCK);
$|=1; ## unbuffer SOCK
select($savehandle); ## restore previously selected handle
Be certain not to mix sysread with other input mechanisms (such
as <SOCK> or read()).
-David