1. Мегаконкурс в апреле "Приведи друзей на codeby". Дарим деньги, подписку на журнал хакер и выдаем статус "Paid Access". Подробнее ...

    Скрыть объявление

Сокет сервер

Тема в разделе "Perl программирование", создана пользователем AndyT, 16 июн 2008.

Наш партнер Genesis Hackspace
  1. AndyT

    AndyT Гость

    Пишу сокет сервер. При запуске сервера родитель Parent отщепляет процесс Worker. Сам Parent висит в блокирующем режиме и ловит подключения. Поймав клиента он передает его в Worker. Worker крутится в бесконечном цикле, каждую секунду опрашивая своих клиентов. Если от кого-то поступает сообщение, он тут же рассылает его всем остальным.
    Проблема в том, что не могу передать от родителя манимупулятор клиента.
    [codebox]#!/usr/bin/perl
    # Server
    #
    use CGI;
    use CGI::Carp qw (fatalsToBrowser);
    use IO::Socket;
    use IO::Select;
    use Time::HiRes qw(sleep); # короткие задержки
    use IO::Handle; # для pipe
    my $q=new CGI;
    $|=1; # запрет буферизации
    print $q->header(-type => 'text/html', -charset => 'windows-1251');
    $select = IO::Select->new();
    $server_port=8888;

    $server=IO::Socket::INET->new(
    LocalPort => $server_port,
    Type =>SOCK_STREAM,
    Reuse =>1,
    Listen => 10
    );
    pipe($reader,$writer); # открываем канал к потомку
    $writer->autoflush(1);
    if($child3=fork()){ # отщепляем потомка
    # блок родителя
    while($client=$server->accept()){
    my ($ip,$port,$host)=who_is($client);
    print $writer $client; # эта строка должна передавать манипулятор клиента в дочерний процесс Worker, но не передает.
    #Обыкновенный скаляр, к примеру $Hello успешно передает.
    # Worker НЕ ВИДИТ КЛИЕНТА
    # В этом проблема!!!!!!!!!
    $Hello="$ip:$port\n";
    print $client "Parent $Hello"; # эта строка успешно возвращается клиенту
    print "<p>Parent: $Hello ";

    }

    }else{
    # Блок потомка Worker
    while(1){
    eval{
    # заключаем в eval, чтобы не блокировалось на sysread
    local $SIG{ALRM}=sub{die "ALRM"};
    alarm 1; #
    sysread($reader,$client,1024); # здесь пробовал разные варианты, но бкзрезультатно
    chomp($client);
    $C{$client}=$line; # собираем клиентов в хэш
    $select->add($client);
    print $client "OK\n"; # пытаемся послать клиенту сообщение, как это сделал родитель. Но не тут то было :rolleyes:
    alarm 0;
    1;
    };
    # дальнейший код не имеет смысла, потому что манипулятор $client не передался от родителя
    @s=$select->can_read(0);
    foreach $sock (@s){
    $rv=$sock->recv($data,1024,0);
    if($data){
    print "<p>$C{$sock}:$data\n";
    }
    }
    foreach my $client(keys %C){
    print $client $EOL; #
    }
    }
    }[/codebox]
    В принципе есть и другие реализации подобного сервера, и они у меня работают, но хочется разобраться с этим.
    К примеру, когда дочерний процесс отщепляется для каждого клиента. Но при этом встает проблема контакта клиентов друг с другом. Нужно вести или общий файл или базу данных. А поскольку опрос клиентов идет с заданной задержкой, то появляются паузы. Если бы удалось реализовать эту схему, то пауз бы уже не было и по этой схеме можно было бы делать игровой сервер.
    Буду благодарен за помощь.
     
  2. Vovochka

    Vovochka Гость

    Конечно понятно, что действиями типа:
    Код (Text):
    print $writer $client;
    sysread($reader,$client,1024);
    Ничего кроме строк вы никуда не передадите.
    Вообще говоря, задача (передача объекта между процессами) интересная, но решения я так и не нашел.
    Если найдете, поделитесь :)
     
Загрузка...
Похожие Темы - Сокет сервер
  1. sasha465
    Ответов:
    1
    Просмотров:
    1.639
  2. areostar
    Ответов:
    1
    Просмотров:
    434
  3. 123456789igor
    Ответов:
    0
    Просмотров:
    1.110
  4. iosif88

    Сокеты

    iosif88, 17 дек 2009, в разделе: .NET
    Ответов:
    1
    Просмотров:
    1.735
  5. Vadik(R)
    Ответов:
    6
    Просмотров:
    17.634

Поделиться этой страницей