in reply to Reading from multiple sockets

Search google or groups.google.com for "perl select socket". Adding your connections to the select array is the proper way to go, but you can work out a hack by putting a timeout on the can_read($timeout). See How to Multiplex a Client using IO::Select and BrowerUk's sample code where he has multiple timeouts on reading sockets. The timeouts would let your multiple socket reads act non-blocking.

I'm not really a human, but I play one on earth Remember How Lucky You Are

Replies are listed 'Best First'.
Re^2: Reading from multiple sockets
by marcovk22 (Initiate) on Oct 23, 2008 at 11:30 UTC
    Thanks for all hints so far...

    I've got the following to work now using IO::Select Properly send & receive to and from server.
    I can esablish a DCC connection over additional socket, but then I only get the data from the DCC socket,
    and no-longer the data from the server socket, untill the DCC socket is closed.....

    $con = IO::Socket::INET->new(PeerAddr=>"$server", PeerPort=>"$port", Proto=>'tcp', Timeout=>'30') || print "Error! $!\n"; $select = IO::Select->new($con); while(@ready = $select->can_write) { for $socket (@ready) { #The DCC Connection if($socket == $dcc) { $talk = <$dcc>; print $talk; #The Server Connection } elsif ($socket == $con) { $answer = <$con>; print $answer; # echo everything that comes from the server t +o screen #lots of other stuff here if ($answer =~ /:(.*)\!.* PRIVMSG $me :\001DCC CHAT chat (\d+) ( +\d+)\001\r\n/) { print "Received dcc from $1 with $2 and $3\n"; $dcc = IO::Socket::INET->new(PeerAddr=>"$2", PeerPort=>"$3", Proto=>'tcp', Timeout=>'30') || print "Error! $ +!\n"; print $dcc "Please Enter Your Password!\n"; $select = IO::Select->new($dcc); } } else { print "more stuff to come here" } } }
      Never mind... I think i fixed it....
      Dunno if its the proper way but hey it works!!!!!!!!!
      $con = IO::Socket::INET->new(PeerAddr=>"$server", PeerPort=>"$port", Proto=>'tcp', Timeout=>'30') || print "Error! $!\n"; $select = IO::Select->new(); $select->add($con); while(@ready = $select->can_write) { for $socket (@ready) { #The DCC Connection if($socket == $dcc) { $talk = <$dcc>; print $talk; #The Server Connection } elsif ($socket == $con) { $answer = <$con>; print $answer; # Stufff if ($answer =~ /:(.*)\!.* PRIVMSG $me :\001DCC CHAT chat (\d+) ( +\d+)\001\r\n/) { print "Received dcc from $1 with $2 and $3\n"; $dcc = IO::Socket::INET->new(PeerAddr=>"$2", PeerPort=>"$3", Proto=>'tcp', Timeout=>'30') || print "Error! + $!\n"; print $dcc "Please Enter Your Password!\n"; $select->add($dcc); } } else { print "Dunno?\n"; exit 1; } } }
        If you are having problems with only getting one socket, maybe your
        while(@ready = $select->can_write) {.....}
        is the wrong while test. Maybe you want to add those that can_read too? If you search google and groups.google for socket examples, you will find they vary depending on code design, but they usually use can_read, or sometimes a while(1){} with can_read and can_write handled in differentl code blocks in the while(1) loop. Just a guess. :-)

        Additionally, IO::Socket has a $sock->connected method that is a useful test to use in a while(1) loop.


        I'm not really a human, but I play one on earth Remember How Lucky You Are