Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Системное программирование > Net::FTP и кол-во попыток соединения


Автор: Sugar84 20.9.2010, 18:53
Добрый вечер.

Есть примерно такой код (сократил чтобы упростить):
Код

use Net::FTP;

my $ftp = Net::FTP->new($serv_name, Debug => 1, 
    Passive => $passive, Timeout => $timeout, );
$ftp->login($user, $passw);

# skipped code
foreach my $file (@files_to_cp) {
    $ftp->put($file);
}


При доступе к одному из серверов   файлы копируются с переменным успехом, в случае удачи программа выдает такое:
Код

Net::FTP=GLOB(0x83121b8)<<< 227 Entering Passive Mode (208,75,230,189,241,167)
Net::FTP=GLOB(0x83121b8)>>> STOR image020.jpg
Net::FTP=GLOB(0x82ceabc)<<< 150 Accepted data connection

и идет дальше.

В случае неудачи получаю такое вот:
Код

Net::FTP=GLOB(0x83121b8)<<< 227 Entering Passive Mode (208,75,230,189,241,167)
Net::FTP=GLOB(0x83121b8)>>> STOR image020.jpg

И вот так скрипт долго висит (2-3  минуты), затем  вылетает с ошибкой:
Код

Can't use an undefined value as a symbol reference at /usr/lib/perl5/vendor_perl/Net/FTP/dataconn.pm line 54.

При этом в tcpdump видно что к серваку улетают syn-пакеты на нужный порт (5 штук), но ответа нету, в нетлисте подключение висит со статусом "synsnt".

Если подправить цикл вот так:
Код

COPY:
foreach my $file (@files_to_cp) {
    eval { $ftp->put($file) };
    if ($@) {
        eval { $ftp->put($file) };
        #+ код счетчика неудачных попыток
}


Происходит то же самое, но вылетает уже с такой ошибкой:
Код

Net::FTP=GLOB(0x82ceabc): Timeout at /home/sugar/name_of_script.pl line 76 
# (кол-во сообщений равно кол-ву неуд. попыток)
Net::FTP: Unexpected EOF on command channel at /home/sugar/Documents/perl/dynamic_ip/ftp_client.pl line 76


Долго думал как это косяк c eval обойти,  и придумал вот такое решение:
Код

PUT:
foreach my $file (@files_to_cp) {
    eval { $ftp->put($file) };
    if ($@) {
        $ftp->close;
        LOGIN:
        while (1) {
            eval { $ftp = Net::FTP->new($serv_name, Debug => 1,
                    Passive => $passive, Timeout => $timeout, );
                $ftp->login($user, $passw) 
                $ftp->cwd($dir_to_copy) };

            next LOGIN if $@;
            last LOGIN;
        }
        redo PUT;
    }
}


Но оно мне кажется громоздким, уродливым и ээ... неправильным

Вопрос 1: можно ли как-то через интерфейс к Net::FTP задать кол-во попыток подключения , т.е. чтоб скрипт не тупо кидал synsent на один порт, а несколько раз пытался именно открыть новое tcp-соединение. Облазил документация и код модулей Net::FTP, Net::FTP::dataconn, IO::Socket, IO::Socket::INET но так ничего и не смог найти.

Вопрос 2: Как задать таймаут соединения? Несмотря на задаваемый параметр Timeout (ставлю 10, 20 и .д.) скрипт все равно висит около 2-3 минут при посылании synsent.

Спасибо за ответы.

Автор: Pfailed 2.10.2010, 07:07
На cpan есть модуль http://search.cpan.org/perldoc?Net::FTP::AutoReconnect. Думаю стоит его посмотреть.

Автор: Sugar84 12.10.2010, 20:31
Спасибо, задачу уже решил, но это отличный модуль.
В следующий раз буду иметь в виду! =)

Автор: ucb1 24.4.2012, 14:58
так в чем же решение

и где найти примеры использования Net::FTP::Autoreconnect

cpan перечисляет комманды без usage  smile 

Автор: Pfailed 25.4.2012, 09:40
Цитата(ucb1 @  24.4.2012,  14:58 Найти цитируемый пост)
и где найти примеры использования Net::FTP::Autoreconnect

Использовать точно также, как Net::FTP.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)