на удаленном хосте висит сокет, с хостом плохая связь, рвется постоянно. Нужна такая прога, которая бы регулярно долбилась на хост:порт и выводиал на stdout то, что валится в сокет.
дык оно отвал соединения не учитывает. т.е. когда не приходит ничего вообще со стороны сервера(самого соединения не существует уже 10 секунд например).
вариант с проверкой на тот случай если коннект удался, но сервер не ответил.
#!/usr/bin/perl -w
use IO::Socket::INET;
use IO::Select;
while (1) {
if ( $socket = new IO::Socket::INET(PeerAddr => 'smtp.mail.ru', PeerPort => 25, Proto => 'tcp', Timeout => 4) ) {
$select = IO::Select->new($socket);
if ( $select->can_read(3) ) {
$answ = <$socket>;
print $answ."\n";
close $socket
} else { print "Cant recv\n" }
}
}
гм. то, что ты предложил, подразумевает раз в 3 секунды чтобы ответ был.
У меня же специфика такова, что соединение надо держать постоянно. Но
оно может в любой момент отвалиться. после того, как оно
отваливается(2-х минутный таймаут), надо начать долбить снова хост-порт
короче я это делаю вот так:
#!/usr/bin/perl -w
use strict;
use IO::Socket;
use IO::Handle;
use Socket;
use Symbol;
use POSIX;
use Net::hostent;
my $port=12345;
my $host="195.28.20.1";
my $host1="127.0.0.1";
my $PREFORK="1";
my $MAX_CLIENTS_PER_CHILD="1";
my %children=();
my $children=0;
my $time=150; # время задержки
# прихода следующего сообщения из сокета в секундах
# если в течении $time секунд не пришло очередное
# сообщение значит отсутствует связь
&exiting();
make_new_child() for 1 .. $PREFORK;
$SIG{ALRM}= sub{die "timeout"};
$SIG{CHLD}=\&REAPER;
$SIG{INT}=\&HUNTSMAN;
while(1){
sleep;
for(my $i=$children; $i<$PREFORK; $i++){
make_new_child();
}
}
sub make_new_child{
my($pid, $sigset, $kidpid, $server, $client);
$sigset=POSIX::SigSet->new(SIGINT);
sigprocmask(SIG_BLOCK, $sigset) or die "can't block SIGINT for fork: $!\n";
die "fork: $!" unless defined do{$pid = fork};
if($pid){
sigprocmask(SIG_UNBLOCK, $sigset)
or die "can't unblock SIGINT for fork: $!\n";
$children{$pid}=1;
$children++;
return;
} else {
$SIG{INT} = 'DEFAULT';
$SIG{CHLD}='IGNORE';
sigprocmask(SIG_UNBLOCK, $sigset)
or die "can't unblock SIGINT for fork: $!\n";
for(my $i=0; $i<$MAX_CLIENTS_PER_CHILD; $i++){
sleep 10;
my ($line);
my $handle = IO::Socket::INET->new( PeerAddr => $host,
PeerPort => $port,
Proto => "tcp");
if(!$handle){
print "READ SOCKET: Ждем начала работы сокета $port на сервере $host\n",qx[date];
last;
} else {
$handle->autoflush(1);
print STDERR "READ SOCKET [соединение с $host:$port]\n";
while(defined($line = <$handle>)){
eval{
alarm($time);
print $line;
&data($line);
};
if($@ and $@=~/timeout/){
print STDOUT "какие-то проблемы со связью, внутри одной итерации цикла находимся более $time секунд\n";
last;
}
}
# last;
}
} exit;
}
}
sub HUNTSMAN{
local($SIG{CHLD})='IGNORE';
kill 'INT' => keys %children;
exit;
}
sub REAPER{
$SIG{CHLD}=\&REAPER;
my $pid = wait;
$children--;
delete $children{$pid};
}
sub data(){ my $x=$_[0]; chomp $x;
my $date=qx[date];
open F, ">>test.log";
print F "$x $date";
close F;
$x=~s!^\#\#(pointdir)\s(.*?)\s(.*?)\s(.*)$!\#\#$2 $3 $4!;
# print "[$x]\n";
# unless($x=~m!^\#\#pointdir!){
qx[perl cl2.pl $1 $2] if $x=~m!^\#\#?(.*?)\s(.*?)\s!;
# }
}
sub exiting{
my @pids= split /\s+/ => qx[ps aux | awk '\$12 ~ /1234.pl/ || \$13 ~ /1234.pl/ {print \$2}'];
do{
if ($$ ne $_){
print "Alert program 1234.pl is running. Exit\n";
exit 0;
}
} foreach @pids;
}
=pod
empty
timeout at 1234.pl line 25, <GEN0> line 478.
READ SOCKET [соединение с 195.28.20.1:12345]
READ SOCKET [соединение с 195.28.20.1:12345]
=cut
p.s. только чето оно лагает жоско. думаю, надо бы ченнить стандартное взять, вдруг есть.