The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Определить жива ли TCP-конекция."
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Определить жива ли TCP-конекция."
Сообщение от mthawk emailИскать по авторуВ закладки(ok) on 27-Окт-04, 12:02  (MSK)
Доброго времени суток многоуважаемые!
Помогите разобраться. стоит задача - демон подключается к некоему удалённому сетевому приложению и держит с ним keepalive TCP коннекцию. Если она порвётся - демон должен об этом узнать.
Насколько я вычитал из манов в модуле IO::Socket есть функция connected. Как маны сообщают, если конекция жива - функция вертает адрес удалённго пира, если нет undef.
В конструкции $peer=$socket->connected; возвращает полнейшую бинарную несвуразицу. что не так?
заранее благодарен.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Определить жива ли TCP-конекция."
Сообщение от mthawk emailИскать по авторуВ закладки(ok) on 02-Ноя-04, 13:02  (MSK)
Многоуважаемые? неужели ни у кого никогда не возникало подобной проблемы?
никто не может помочь?


  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Определить жива ли TCP-конекция."
Сообщение от Александр emailИскать по авторуВ закладки(??) on 02-Ноя-04, 15:35  (MSK)
Бесплатный совет: учись задавать вопросы.
Чтобы что-то сказать, нужно как минимум, язык программирования (PHP? Perl?) и используемую библиотеку. Не помешает ОС.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Определить жива ли TCP-конекция."
Сообщение от mthawk emailИскать по авторуВ закладки(ok) on 02-Ноя-04, 17:11  (MSK)
>Бесплатный совет: учись задавать вопросы.
>Чтобы что-то сказать, нужно как минимум, язык программирования (PHP? Perl?) и используемую
>библиотеку. Не помешает ОС.
Вообще то эхотага называется "Программирование под Юникс".... думаю не нужно быть семи пядей во лбу, что бы понять, что пишу не для полуоси. (ASP 9.0 / RedHat 9)
Ключевая тема сообщения - Perl. Опять же не слишком много ума стоит преложить, что бы догадаться, что за язык используется.
Ну и наконец третье: цитируя самого себя "Насколько я вычитал из манов в модуле IO::Socket есть функция connected" - какую же я библиотеку использую, а?
встречный совет - зрите глобальней! читайте мелкий текст, или просто сходите  к окулисту.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

14. "Определить жива ли TCP-конекция."
Сообщение от mthawk emailИскать по авторуВ закладки(ok) on 23-Ноя-04, 16:40  (MSK)
Огромное спасибо всем, кто принял участие в дисскуссии!
После многочасаовых изысканий нашел довольно приемлемый вариант.
публикую его тут, если вдруг кому понадобится:

#!/usr/bin/perl
use IO::Socket;
sub err
    {
    $reason=shift;
    if ($reason ne 'Resource temporarily unavailable'){  #Если сокет поднят, но данных для чтения нет
    $netfault=1;
    $reconnect=1;
    close($socket);
    }
    }
sub dc_connect
    {
    $netfault=0;
    $reconnect=0;
    $socket = IO::Socket::INET->new(PeerAddr=> "localhost",
    PeerPort => 7777,
    Proto => 'tcp',
    Timeout => 1,
    Type => SOCK_STREAM) || &err("$!");
    if ($netfault)
        {
        print "Can't establish connection: $reason\n";
        $reconnect=1;
        }
    }
################# GENERAL VARIABLES ###################
$netfault=0;                    #network fail
$reconnect=1;                   #need try to connect
while (1)
{
################ ESTABLISH CONNECTION##################
&dc_connect if ($reconnect);
############## CHECK NETWORK CONNECTION ##################
##################### NET CHECK ##########################
recv ($socket,$netdata,512,MSG_DONTWAIT)||&err("$!") if (!$netfault);
print "Error receving: $reason\n" if ($netfault);
if ($netdata)
    {
    print "recv from socket:$netdata";
    $netdata='';
    }
##########################################################

sleep 1;
}

  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "Определить жива ли TCP-конекция."
Сообщение от rWizard emailИскать по авторуВ закладки(ok) on 02-Ноя-04, 21:48  (MSK)
Сегдня буду разбираться с этим, в случае положительного результата - доложу
  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "Определить жива ли TCP-конекция."
Сообщение от mthawk emailИскать по авторуВ закладки(ok) on 03-Ноя-04, 21:29  (MSK)
>Сегдня буду разбираться с этим, в случае положительного результата - доложу

Очень жду Вашего результата. сам - разбился в лепёшку об этот "камень преткновения".
Единственный способ, что для себя нашел - анализировать что выдает netstat.
Еще "Сишники" посоветовали скажем раз в 1 - 10 секунд отправлять в сокет 0 байт и слушать return функции send()....
Если  0 - все ок, если -1 - конекция умерла. - экспериментировал -возвращается 0 в любом случае...

  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Определить жива ли TCP-конекция."
Сообщение от rWizard emailИскать по авторуВ закладки(ok) on 04-Ноя-04, 01:30  (MSK)
Пока узнал вот что:
connected возвращает undef, только если руками засрываеш соединение
если послать определенное кол-во данных в "мертвый" сокет получаем Broken pipe;
так-же пробовал по спотреть return write() и send()
но!
я паралельно вижу _живое_ соеденинеие с помощю sockstat (netstat)
те, операционка считает подключение ещё живым.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "Определить жива ли TCP-конекция."
Сообщение от Soldier Искать по авторуВ закладки(??) on 04-Ноя-04, 10:12  (MSK)
>Еще "Сишники" посоветовали скажем раз в 1 - 10 секунд отправлять в
>сокет 0 байт и слушать return функции send()....
>Если  0 - все ок, если -1 - конекция умерла. -
>экспериментировал -возвращается 0 в любом случае...

Я на C делал так:
С помощью select проверял есть ли данные для чтения. Если ответ
положительный (данные для чтения есть) и количество байт для чтения равно
0, то соединение "умерло". Количетсво байт для чтения можно получить
функциями read, recv  и т.д. или через ioctl, например в Линуксе,
ioctl(sock_fd,FIONREAD,&nbytes). Возможно, подобная схема реализуема и на
перле.


P.S. Демон на перле - извращение, ИМХО :)))

  Рекомендовать в FAQ | Cообщить модератору | Наверх

8. "Определить жива ли TCP-конекция."
Сообщение от rWizard emailИскать по авторуВ закладки(ok) on 04-Ноя-04, 13:24  (MSK)
Решение нашел, но кривое.

# cat conn.pl
#!/usr/bin/perl
use strict;
use IO::Socket;
use Fcntl qw(:mode);
$|=1;

my $host = '127.0.0.1';
my $port = '1234';
my $r = IO::Socket::INET->new ( Proto => "tcp",
                             PeerAddr => $host,
                             PeerPort => $port ) || die "can`t connect";


while ('true')
{
my @a = $r->stat;
print join(':',@a), "\n";
printf "Permissions are %04o\n", S_IMODE($a[2]), "\n";
print $r "asdfa sdfa sdf asdf adsf ";
sleep 4;
}

вывод:
# ./conn.pl
0:0:49590:0:0:0:0:0:0:0:0:57344:0
Permissions are 0666
0:0:49590:0:0:0:0:0:0:0:0:57344:0
Permissions are 0666

# в этот момент я убиваю сервер

0:0:49298:0:0:0:0:0:0:0:0:57344:0
Permissions are 0222
0:0:49152:0:0:0:0:0:0:0:0:57344:0
Permissions are 0000
Broken pipe

Комментировать или из кода поятно?

  Рекомендовать в FAQ | Cообщить модератору | Наверх

11. "Определить жива ли TCP-конекция."
Сообщение от mthawk emailИскать по авторуВ закладки(ok) on 05-Ноя-04, 15:55  (MSK)
В принципе все доступно, только разве что в стремлении к ясности и новым знаниям просил бы дать ремарки на 2 строчки Вашего кода. а именно :

my @a = $r->stat;
printf "Permissions are %04o\n", S_IMODE($a[2]), "\n";

Заранее благодарен.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

12. "Определить жива ли TCP-конекция."
Сообщение от rWizard emailИскать по авторуВ закладки(ok) on 06-Ноя-04, 10:02  (MSK)
perldoc -f stat
stat () - возвращает массив с парметрами файла.
(в данном случае с параметрами сокета)
нас интересует 2-ая запись - права доступа.
сокет становится read-only, когда соединение рвется.
(если я все павильно понял)

S_IMODE()
(perldoc POSIX)
преобразует mode, возвращаемый stat() в привычный вид (user-group-other)


  Рекомендовать в FAQ | Cообщить модератору | Наверх

13. "Определить жива ли TCP-конекция."
Сообщение от Soldier Искать по авторуВ закладки(??) on 06-Ноя-04, 14:29  (MSK)
Прошу прощения, что вклиниваюсь...
Я на перле почти не програмлю, так что сорри если что-то невпопад:

сервер srv.pl:

#!/usr/bin/perl
use IO::Socket;
$srv_sock = new IO::Socket::INET (
LocalHost => 'localhost',
LocalPort => '4000',
Proto => 'tcp',
Listen => 1,
Reuse => 1,
);

die "Could not create socket: $!\n" unless $srv_sock;

$clnt_sock=$srv_sock->accept();
print $clnt_sock "I am here\n";
while (<$clnt_sock>) {
print "Got: ",$_,"\n";
}
close($srv_sock);
#==  cut ======================


Клиент cln.pl:


#!/usr/bin/perl
use IO::Socket;
use IO::Select;
use Fcntl qw(:mode);

$sock = new IO::Socket::INET (
      PeerAddr => 'localhost',
      PeerPort => '4000',
      Proto => 'tcp',
);
die "Could not create socket: $!\n" unless $sock;

@a = $sock->stat;
print join(':',@a), "\n";
printf "1. Permissions are o\n", S_IMODE($a[2]), "\n";
print $sock "asdfa sdfa sdf asdf adsf ";

sleep 5;

print "Passed sleep\n";

@a = $sock->stat;
print join(':',@a), "\n";
printf "2. Permissions are o\n", S_IMODE($a[2]), "\n";
print $sock "asdfa sdfa sdf asdf adsf ";

$readfs=new IO::Select();
$readfs->add($sock);

while ($res = IO::Select->select($readfs, undef, undef, 0)) {
printf "1. res=%s\n", $res;
foreach  $rh (@$readfs) {
  if ($rh == $sock) {
   $buf = <$rh>;
   if (!length($buf)) {
    print "I got 0 bytes to read - supposed connection was closed\n";
    exit;
   }
   printf "Got from server: '%s', %u\n", $buf,length($buf);
  }
}
$readfs->remove($rh);
}

print "Prepare to send data\n";
print $sock "Hello, world!\n";
print "Data  was sent\n";
close($sock);
#==== cut ====================

1.
Запускаю srv.pl
Запускаю cln.pl
Получаю на клиенте
4:4776:49663:1:1000:1000:0:0:0:0:0:1024:0
1. Permissions are 0777

И спустя пять секунд:

Passed sleep
4:4894:49663:1:1000:1000:0:0:0:0:0:1024:0
2. Permissions are 0777
1. res=3
Got from server: 'I am here
', 10
Prepare to send data
Data  was sent

Получаю на сервере:
Got: asdfa sdfa sdf asdf adsf asdfa sdfa sdf asdf adsf Hello, world!

2. Запускаю srv.pl
запускаю cln.pl

Получаю:
4:4946:49663:1:1000:1000:0:0:0:0:0:1024:0
1. Permissions are 0777

Примерно через секунду убиваю сервер.
Еще через четыре секунды получаю:

Passed sleep
4:4946:49663:1:1000:1000:0:0:0:0:0:1024:0
2. Permissions are 0777
1. res=3
Got from server: 'I am here
', 10
1. res=3
I got 0 bytes to read - supposed connection was closed


Т.е. трюк со stat почему-то не сработал, возможно я сделал, что-то не так.
Но select отработал как надо.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

9. "Определить жива ли TCP-конекция."
Сообщение от rWizard emailИскать по авторуВ закладки(ok) on 04-Ноя-04, 13:28  (MSK)
2 Soldier
во-первых, каждый пишет на чем умеет
во-вторых, перл мне наравиться, потому, что он более высокого уровня, те на создание нужного алгоритма ужодить меньше вермени. (не сочтите это за попытку развязвть "религиозную войну" )
  Рекомендовать в FAQ | Cообщить модератору | Наверх

10. "Определить жива ли TCP-конекция."
Сообщение от Soldier Искать по авторуВ закладки(??) on 04-Ноя-04, 14:41  (MSK)
2 rWizard

Признаю, что перл - довольно мощная штука, хоть мне он и не нравится, но...

Во-первых, знать С должен каждый уважающий себя юникс-программер, ИМХО.
Во-вторых, вот потому, что он (перл) более высокого уровня, плюс ко всему
еще и интерпретатор, писать на нем демона и есть извращение, ИМХО ;-)

P.S. Никого не хотел задеть или обидеть, просто высказал свое мнение.

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру