код:
use IO::Socket;
use IO::Select;
use HTTP::Daemon;
use POSIX;
use Fcntl;
$|=1;
$port = 5555;
$max_clients = 35; #SOMAXCONN
%logon =();
%nick =();
%SID =();
%log_time =();
%perms =();
%IP=();
$server = HTTP::Daemon->new(Proto => \'tcp\', LocalPort => $port, Listen => $max_clients) or die "Can\'t make server socket: $@\\n";
nonblock($server);
$select = IO::Select->new($server);
print "[Chat server runing on ", $server->url, "] \\n\\n";
while (1)
{
foreach $client ($select->can_read(1))
{
if ($client == $server)
{
#обработка событий подключения
my $new_client = $server->accept();
if(defined($new_client))
{
print "Client accepted\\n";
nonblock($new_client);
$select->add($new_client);
$logon{$new_client}="";
$nick{$new_client}="";
#присвоение остальных переменных
}
}
else
{
my $data = \'\';
my $rv = $client->recv($data, POSIX::BUFSIZ, 0);
unless (defined($rv) && length $data)
{
#очистка переменных
#delete $inbuffer{$client};
#delete $outbuffer{$client};
#delete $ready{$client};
$select->remove($cllent);
delete $client;
print "Client closed\\n";
next;
}
else
{
my $request = $client->get_request();
if (defined($request))
{
if ($request->method eq \'GET\')
{
#обработка $Id.html
}
else
{
#выдать сообщение о неверном запросе и записать в лог ошибку.
}
}
}
}
}
}
sub nonblock {
my $sock = shift;
if ($^O eq \'MSWin32\')
{
sub FIONBIO { 0x8004667e }
my $set_it = "1";
ioctl($sock, FIONBIO, $set_it)
or die "Can\'t set the socket non-blocking: $!";
} else {
my $flags = fcntl($sock, F_GETFL, 0)
or die "fcntl fails with F_GETFL: $!";
fcntl($sock, F_SETFL, $flags | O_NONBLOCK)
or die "fcntl fails with F_SETFL: $!";
}
}
Эта прога - многопотоковый сервер, который акцептит клиентов и держит связь с ними.
Если какой-то клиент отключается срабатывает болк
unless (defined($rv) && length $data) НО дальше идёт глюк - все последующие подключения акцептятся, но не обрабатываются, то есть $new_client - undefined, НО и ошибки не происходит и клиент сообщает об удачном коннекте.
Если убрать
unless (defined($rv) && length $data) - всё работает нормально (но обрабатывать дисконнекты - обязательно) Как быть?