Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

multiple socket streams

by Forsaken (Friar)
on Jun 07, 2004 at 03:13 UTC ( #361854=perlquestion: print w/replies, xml ) Need Help??

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

Edit: Solution found. Many thanks.

lowly initiate seeking the infinite wisdom of the higher level monks...

Currently working on a script that has 2 separate socketstreams, which for the sake of simplicity i'll refer to as SOCK1 and SOCK2. Normal method to read from a filehandle that I'd use is while(<SOCK1>) but when doing so it chunks out all the data, as it should, but then sits around waiting for more, while I want it to move on with the rest of the script, in this case repeating the process for SOCK2. Anyone got any idea on how to go about this? Details: Activeperl 5.8.3, WinXP.

Replies are listed 'Best First'.
Re: multiple socket streams
by Zaxo (Archbishop) on Jun 07, 2004 at 03:36 UTC

    Take a look at IO::Select, a wrapper for four arg select. That will let you read whichever source has data ready.

    After Compline,
    Zaxo

      looks like a pretty OO version of the little stream-management thingy I built myself, but the problem persists. It's not so much a matter of knowing where there's data, as it is to determine when there's no more data left, and hence break away from this stream and move on the next. Using a timed event might do the trick as was suggested earlier, but that's not really what i would call an elegant solution.
        but that's not really what i would call an elegant solution.

        Yes, it sucked :-)

        What about doing a shift in the socket, matching what's returned against alphanum, and if nothing, move out of the sub ?

Re: multiple socket streams
by hsinclai (Deacon) on Jun 07, 2004 at 03:28 UTC
    Maybe using alarm/timeout on the socket?
    $SIG{'ALRM'} = sub { .. invoke the switch over to other socket .. }; my $alarmtime = "10"; sub connect_to_sock1 { ... alarm($alarmtime); ... }
Re: multiple socket streams
by baruch (Beadle) on Jun 07, 2004 at 03:23 UTC

    How does it know it has reached the end of the data?


    בּרוּך
      good question...the connection itself is in fact a socket connection to an irc server. I create the connection, and then initiate the while loop to read all the data buffered at that time for the filehandle. One way or another I need to figure out how to persuade it that when there's nothing left it can move on.
      what i thought was that once the buffer's empty, while ($text = <SOCK1>) would return false and the loop would stop.
Re: multiple socket streams
by kragen (Sexton) on Jun 07, 2004 at 18:56 UTC
    sysread() on a socket will read whatever data is available, then return; except when there is no data available, in which case it will hang until some data is available. You can avoid this by only calling sysread() when select() tells you there's data. <> will keep reading until it gets a whole line, which means that your IRC script will occasionally hang when it gets part of a line in one packet, causing select() to tell you there's data, but the next packet doesn't show up for a while. I'm not sure how <>'s buffering will interact with select(). I think it's possible for select() to say no data is available, but <> to have data waiting in a read buffer, but because <> has the other problem described above (when used with select()) I haven't used it enough to find out for sure. If this putative problem exists, it will manifest as your program receiving some lines of input long after they were sent.
      According to the docs, using buffered reading such as <> combined with select() is a recipe for disaster :-) I gave it a try with sysread() instead and that seems to work fine. As long as there is a timeout on select() to avoid falling into the same trap as before, it runs through each of the filehandles nicely, checks if there's any incoming data, and if so, reads it in.

      Great tip, tx.
Re: multiple socket streams
by sgifford (Prior) on Jun 07, 2004 at 20:59 UTC
    Another solution that didn't come up is using nonblocking sockets. See the Blocking argument to IO::Socket::INET.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://361854]
Approved by davido
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2021-05-12 08:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (125 votes). Check out past polls.

    Notices?