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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Работа с сокетами, в одном процессе 
:(
    Опции темы
Anarki
Дата 27.7.2005, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Нужно работать с сокетами - отправить и принять данные, причём так, чтобы сокеты не мешали друг другу, не ждали пока первый сокет что-то сделает(т.е. неблочные).
fork() - юзать нельзя, как я понимаю нужно использовать IO::Select, или я нашёл модуль NET::Sockets::Nonblock. но ни там, ни там не смог разобраться

Конретно, задача состоит в том чтобы послать HTTP запрос и получить ответ, сокеты пусть работают пачками, по 20-25 штук, чтобы не грузить проц, каждому сокету - по урлу...


--------------------
PM WWW   Вверх
nerezus
Дата 27.7.2005, 19:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


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

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



Может threads?
Имхо не то, но работать будет...


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
sharq
Дата 27.7.2005, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Perl Liker
**


Профиль
Группа: Участник
Сообщений: 841
Регистрация: 13.12.2004
Где: Ростов-на-Дону

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



Anarki тебе нужно написать многопоточный сервер, без использования fork?
Есть решение в книги "Perl Cookbook", книгу можешь забрать в соотв. разделе.

smile


--------------------
[color=gray]There's More Than One Way To Do It[/color]
PM MAIL WWW ICQ Skype   Вверх
Anarki
Дата 27.7.2005, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(sharq @ 27.7.2005, 20:23)
Anarki тебе нужно написать многопоточный сервер, без использования fork?
Есть решение в книги "Perl Cookbook", книгу можешь забрать в соотв. разделе.

smile

Клиент, клиент а не сервер, если бы я хотел сервер, я бы уже сделал его.
nerezus
Код

use threads; 

имеешь ввиду?
Мне такое решение не нужно, так как Perl не собран с поддержкой их, хотелось бы мультиплатформенное приложение.

Ладно, забил на то, что нельзя использовать fork(), хотя это онимает много памяти
Вот кусок кода
Код

#!/usr/bin/perl -w
=pod AUTHOR
Anarki, ICQ: 417615
SmartDev Team (http://smartdev.ru)
=cut
#use strict;
use URI;
use URI::Split qw(uri_split);
use IO::Socket;
use IO::Select;
use Time::HiRes qw(gettimeofday);
my $referer = $ARGV[0] || "http://microsoft.com";
my $user_agent = "Mozilla/4.0 (compatible; MSIE 5.0; Windows XP)";
my $threads = $ARGV[1] || 2; # êîëè÷åñòâî ïîòîêîâ

my @threads = ();
my @forked = ();
my $counter = 0; # ÷èñëî îáðàáîòàííûõ óðëîâ
my $starttime = time();  # vremya starta scripta

# ñàìà ôóíêöèÿ
sub visit {
    my ($scheme, $auth, $path, $query, $frag) = uri_split($_[0]);
    print "Parsing url: $_[0] ref: $referer\n";
    my $socket = IO::Socket::INET->new(PeerAddr => $auth, PeerPort => 80, Proto => 'tcp', Type => SOCK_STREAM, Timeout => 5) or return;

    my $write_set = new IO::Select();
    $write_set->add($socket);

    my @ready = $write_set->can_write(5);
    foreach my $ready(@ready) {
         my $starttime = gettimeofday();
         $query ||= '';
         my $out = "GET ".$_[0]." HTTP/1.1\r\n";
                $out.="Accept: */*\r\n";
                $out.="Accept-Language: ru\r\n";
                $out.="Accept-Encoding: gzip, deflate\r\n";
                $out.="Host: ".$auth."\r\n";
                $out.="Connection: Close\r\n";
                $out.="User_Agent: $user_agent\r\n";
                $out.="Referer: $referer\r\n\r\n";
                $out.="\r\n";
        
         print $ready $out;
         close($ready);
         printf "worked: %f\n",(gettimeofday() - $starttime);
    }
}

# óáèâàåò ïîðîæäåííûå ïðîöåññû
sub killall {
    foreach my $pid (@forked) {                                      
    ## Ïî êàæäîìó ïðîöåññó èç ñïèñêà
        waitpid($pid,0);  ## Äîæèäàåìñÿ åãî çàâåðøåíèÿ
    kill("TERM" => $pid);  ## À ëèøü çàòåì óáèâàåì åãî
    }                                                                
    undef @forked;
    undef @threads;  ## Äåëàåì ìàññèâû @forked è @threads íåîïðåäåëåííûìè
}

my $finurl =undef;
open($finurl,"<","in.urls");
while(my $site = <$finurl>) {
    chomp($site);
    if (substr($site,length($site)-1) eq "\r") {
                substr($site,length($site)-1) = '';
    }
    push(@threads,$site);
    if (scalar(@threads) eq $threads) {
        for (my $j=0;$j<$threads;$j++) {  ## Îòêðîåì öèêë ïî ÷èñëó ïîòîìêîâ
                if (my $pid=fork()) {  ## Îòâåòâèì ïðîöåññ
                push(@forked,$pid); ## Çàïîìíèì èäåíòèôèêàòîð
                } else {
                visit($threads[$j]);  ## parsim
                exit;  ## Âûõîäèì èç ïîòîìêà
                }
        }
        killall();
    }
}
close($finurl);

# ×òî-òî îñòàëîñü??
if (scalar @threads > 0) {
    for(my $j=0;$j<scalar(@threads);$j++) {
        if (my $pid=fork()) {  ## Îòâåòâèì ïðîöåññ
            push(@forked,$pid); ## Çàïîìíèì èäåíòèôèêàòîð
            } else {
            visit($threads[$j]);  ## parsim
            exit;  ## Âûõîäèì èç ïîòîìêà
            }
    }
    killall();
}



# ñòàòèñòèêà
# vremya kogda script zakonchil rabotu
my $endtime = time();
print "Script worked for : ".($endtime-$starttime)."sec\n";


Функция visit() работает в цикле, точне в отдельном потоке(процессе), где ей передаётся аргумент вида : http://www.site.com/index.php?page=3
Но,после обработки достаточного числа урлов - она останавливается... не выводится сообщение Script worked for... и т.п. в чём может быть проблема?я думаю где-то в неправильной работе с IO::Select, а может сервак сам убивает процесс... =\



Вообще задача стоит установить таймаут для сокета,и обрабатывать их раздельно, не мешая друг другу, поменьше тормозя на урлах, Timeout обычный не помогает, поэтому и приходится изощряться

Это сообщение отредактировал(а) Anarki - 27.7.2005, 23:30


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


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

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


 




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


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

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