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

Dear Monks!

I'm pretty new to working with sockets in perl, and this is my first post so be gentle :-D
Looked around for days for a proper solution for my IRC/DCC problem but couldn't find one.

The connection to the server uses a socket with a neverending while loop:

sub connection { # Make The Initial Server Connection! # $con = IO::Socket::INET->new(PeerAddr=>"$server", PeerPort=>"$port", Proto=>'tcp', Timeout=>'30') || print "Error! $!\n"; while($answer = <$con>) {

All works fine untill i want to make a DCC connection using another socket:

$dcc = IO::Socket::INET->new(PeerAddr=>"$2", PeerPort=>"$3", Proto=>'tcp', Timeout=>'30') || print "Error! $!\n"; print $dcc "Connection Established!\n"; while ($talk = <$dcc>) {

The first loop is being blocked?
I only receive input/output from the second loop untill this one is closed again, then the first loop continues....
How can i get a continuous flow from both?
I've read some bits about IO::Socket::Select, and have also been playing with multiple threads, but i prefer the first option... Any help is very appreciated!

Replies are listed 'Best First'.
Re: Reading from multiple sockets
by Fletch (Bishop) on Oct 21, 2008 at 13:45 UTC

    There's always POE::Component::IRC which handles all the nasty select and network mucking about for you allowing you to concentrate on what you want to do, not the underlying transport.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Reading from multiple sockets
by zentara (Cardinal) on Oct 21, 2008 at 12:19 UTC
    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
      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; } } }