Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Блокирующие сокеты, обход блокировки 
:(
    Опции темы
Linco
Дата 22.12.2005, 16:43 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Здравствуйте! Значит имеется следующая ситуация, есть необходимость в создании клиента и сервера, которые должны работать в режиме запрос-ответ т.е.
Клиент: запрос
Сервер: выбор из БД, ответ
Клиент: обработка данных, ответ новыми данными
Сервер: добавление данных в БД, закрытие
Я не специалист в перле в итоге родилось нечто следующее:
сервер:
Код

   my $server = IO::Socket::INET->new(
                                Proto     => 'tcp',
                                LocalPort => $server_port,
                                Type      => SOCK_STREAM,
                                Reuse     => 1,
                                Listen    => 10 );   # or SOMAXCONN
     if(!$server)
    {
        print("Couldn't be a tcp server on port $server_port : $@\n");
        exit;
    }
    else
    {
        print("Server created on port: $server_port $@\n");
    }
    $server->autoflush(1);
    while ($client = $server->accept())
    {
        $server->autoflush(1);
        $client->autoflush(1);
        print $client "Connection accepted";
        print ('Connection from ',$client->peerhost(),':',$client->peerport()," accepted. \n");
        while (<$client>) {
            if ($_ = 'stats'){
             statsquery();//функция делает запрос к БД, получает данные и пишет их в массив @dblist как CSV, она нам не интересна :)
             last;
            }#if
        }#while
        print "Sended \n @dblist";
        print $client @dblist or die "Cannot send"; 
    }
    $server->close;
    print("Server closed");
}

Клиент:
Код

    my $client = IO::Socket::INET->new(Proto     => "tcp",
                                        PeerAddr  => $server_addr,
                                        PeerPort  => $server_port,
                                        Type=> SOCK_STREAM)               
     or die "Cannot connect to host: $server_addr:$server_port \n";
    $client->autoflush(1);
    $client->recv(my $text,128);
    print "$text\n";
     $client->send("stats") or die "Not sended: $!\n";
   
    $client->recv($buf,1024);//если этого нет то на сервере все проходит, только клиент естественно данные не получает
    print $buf;
    close ($client);
    print "Client closed";
}

если есть сервер останавливается на if ($_ = 'stats')
Я так понимаю что срабатывает блокировка, и почему-то даже посланная 'stats' до сервера не доходит. Как это обойти не представляю. Пробовад и с Select и c FORK но видимо не так пробовал. Клиент будет один и обмен данными будет строго последовательный так что не представляю почему он блокирует оба конца smile
может подскажет кто?
  Вверх
stan777
Дата 12.4.2007, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 29.1.2007

Репутация: нет
Всего: нет



Blocking => 0,                   # This line is very important
Как написано в спане это вроде должно отключить блокировку сокета. Хотя сам еще не пытался вот только пробую.
PM MAIL   Вверх
KSURi
Дата 12.4.2007, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 887
Регистрация: 8.6.2006
Где: Russia

Репутация: 20
Всего: 27



Не понимаю при чем тут Nonblocking?

Когда ты делаешь recv у сокета, он "блокируется", те управление в основную программу не возвращается, пока туда не придёт хотя-бы 1 байт. А неблокирующий режим позволят не ждать завершения операции, те управление сразу вернётся в главную программу. Тоже самое относится к вызовам send, write и тд.

Добавлено через 14 минут и 20 секунд
c.pl:
Код

#!perl -w

use strict;
use warnings;
use IO::Socket;

my $c = IO::Socket::INET->new(PeerAddr => '172.22.6.236',
                              PeerPort => 6236,
                              Proto => 'tcp') || die;
$c->autoflush(1);

my $in;
$c->recv($in, 20) || die 'no handshake';
print $in, "\n";
$c->send('stats');
$c->recv($in, 1024) || die 'no answer';
print $in, "\n";

$c->shutdown(0);


s.pl:
Код

#!perl -w

use strict;
use warnings;
use IO::Socket;

my $s = IO::Socket::INET->new(LocalAddr => '172.22.6.236',
                              LocalPort => 6236,
                              Proto => 'tcp',
                              Listen => 1) || die;
$s->autoflush(1);

while(1)
{
    next unless my $c = $s->accept;
    $c->send('Connection accepted');
    my $in;
    $c->recv($in,5) || last;
    print $in, "\n";
    $in eq 'stats' || last;
    
    # do some actions here
    $c->send('Ok, test was successful');
}

$s->shutdown(0);



--------------------
Died at Life.pl line 21
PM Jabber   Вверх
stan777
Дата 12.4.2007, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 145
Регистрация: 29.1.2007

Репутация: нет
Всего: нет



Цитата(KSURi @ 12.4.2007,  12:22)
Не понимаю при чем тут Nonblocking?

Ну как бы и не причем, притом что у него один клиент к серверу конектится smile.  Вот если бы клиент имел бы больше одного конекта и хотел бы из них одновременно качать и сохранять, то думаю бы потребовались сокеты без блокирования. 

Это сообщение отредактировал(а) stan777 - 12.4.2007, 17:17
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0459 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.