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

I have been having an issue with an app I am writing as an irc proxy to keep persistant connection to irc and allow a client to attach and detach. I have an irc socket which reads and writes to irc which should be connected at all times, I have a listen socket that simply listens for client connections and spawns a client socket to read and write to and from.

The problem is when I connect a clien tto the app and then disconnect, the ircsocket which is still suppose to be connected returns an EOF in it's sysread over and over again and the app turns into a big endless loop.

Here is some code:

while(@ready = $sel->can_read()) { print "Client Count => #".$sel->count(),"\n"; foreach my $fh (@ready) { if ($fh == $usersock) { print "New usersock!\n"; # Create a new socket my $new = $usersock->accept(); $sel->add($new); } else { if ($fh == $ircsock) { print "IRCSOCK!\n"; my $ircdata; # This is the sysread below that returns an EOF while r +eading $ircsock if (sysread($ircsock, $ircdata, 512)) { chomp($ircdata); print "Raw Server Data => $ircdata\n"; if ($ircdata =~ /^\:/) { if ($sel->count() < 3) { print "Loggin to $LOG\n"; open(LOG, ">>", $LOG) || next; print LOG $ircdata,"\n"; close(LOG); #next; } foreach my $client ($sel->can_write()) { if ($client && $client != $ircsock && $client +!= $usersock) { print $client $ircdata,"\n"; } } } else { # We must respond to PING's to avoid being discon +nected. print $ircsock "PONG $1\n" if ($ircdata =~ /^PING +(.*)/i); } } } else { print "New client sock!\n"; my $clientdata; if (sysread($fh, $clientdata, 512)) { chomp($clientdata); print "Raw Client Data => $clientdata\n"; if ($clientdata =~ /^\:/) { print $ircsock $clientdata,"\n"; } else { if ($clientdata =~ /PASS|NICK|USER/) { my @login = split(/\n/, $clientdata); my ($pass, $nick); foreach my $line (@login) { $pass = $1 if ($line =~ /^PASS\s*(\ +w+)/); $nick = $1 if ($line =~ /^NICK\s*(\ +w+)/); $conf{'HOST'} = $1 if ($line =~ /^USER\s+\w ++\s+(\S+)/); } if ($pass && $nick) { print "Pass and Nick seen!\n"; if ($pass eq $conf{'PASS'} && $nick eq $con +f{'NICK'}) { print $fh "Login Successful ... Proceedi +ng With Connection!\n"; } else { print "I think it is here!\n"; print $fh "Login Failed ... Incorrect Us +ername or Password!\n"; $sel->remove($fh); $fh->close(); } } else { if ($clientdata =~ /PASS/) { print "Or it could be here!\n"; print $fh "[ERROR]: Login Parse Error .. +. Exiting!"; $sel->remove($fh); $fh->close(); } } } elsif ($clientdata=~ /^JOIN\s*\#(\S+)/) { print "JOIN!\n"; print $fh ":$conf{'NICK'}!~$conf{'NICK'}\@$con +f{'HOST'} JOIN :#".$1,"\n"; print $ircsock "NAMES #".$1,"\n"; print $ircsock "TOPIC #".$1,"\n"; } elsif ($clientdata =~ /^flush\s*(\d*)\s*(\d*)/) + { my $lb = ($1) ? $1 : 0 ; my $interval = ($2) ? $2 : 0 ; print "Flush detected ... Buffer Lines => $lb, + Interval => $interval\n"; if (-e $LOG) { open (LOG, "<", $LOG) || print $fh "PRIVMSG $conf{'NICK'} :[ERROR +]: Issue opening $LOG\n", next; my $cnt = 0; while (<LOG>) { if ($lb) { if ($cnt < $lb) { print $fh $_,"\n"; $cnt++; } else { sleep($interval); $cnt = 0; } } else { print $fh $_,"\n"; } } close(LOG); unlink($LOG); } else { print $fh ":$conf{'NICK'}!$conf{'NICK'}\@$c +onf{'HOST'} PRIVMSG $conf{'NICK'} :There was no log file detected!\n" +; } } else { print "Server data that did not match!\n"; print $ircsock $clientdata,"\n"; } } } else { print "Client exited!\n"; # Client has exited so we remove the socket handle f +rom select and close it. $sel->remove($fh); close($fh); } } } } }
Please excuse all the debug print statements... :-)

Anyone have any ideas what the issue may be?

Replies are listed 'Best First'.
Re: EOF being read from open socket?
by ikegami (Patriarch) on Aug 23, 2006 at 20:15 UTC
    Remove the dead socket from $sel like you do when clients "exit".
      That socket has to stay in select because it is still active, connected and needs to be read from and written to.
        What makes you think it's still connected? What is sysread returning? 0? undefined? If undefined, what's in $!?