I ran into an issue where Net::FTP was failing at random while connecting many times over the life of a script. I searched for a solution only to find that others were having similar issues. It seems that this excellent module does not actually check to see if the port that is used for connection is working correctly before forging on. The only way around it (that I have found) was to check for the error and reconnect on-the-fly until a working port has been found. It is not a perfect solution as it takes extra resources that could be used elsewhere if the error check was done at the module level, but it has worked well for me so far.
I just thought others might find this of some help if they find themselves in the same situation. I was not really sure where to post this, so I asked on the CB and pointed here (thank you all for the help!). If you all find this helpful at all, please share it with others at your pleasure.
#!/usr/bin/perl use strict; $|++; use Net::FTP; my $S = { 'Server 1' => { 'Host' => 'myHost1', 'IP' => '10.10.10.10', 'user' => 'myUser1', 'pass' => 'myPass1', 'desc' => 'Remote Host #1', }, 'Server 2' => { 'Host' => 'myHost2', 'IP' => '10.10.11.10', 'user' => 'myUser2', 'pass' => 'myPass2', 'desc' => 'Remote Host #2', }, 'Server 3' => { 'Host' => 'myHost3', 'IP' => '172.16.22.105', 'user' => 'myUser3', 'pass' => 'myPass3', 'desc' => 'Workstation #1', }, }; &FTP_get_file( { source_name => 'thumbs.db', target_name => '', source_path => '/', target_path => './', server => 'Server 1', } ); exit; ###################################################################### +########## sub FTP_connect() { my $params = shift; my $server = $params->{'server'}; my $ftp; if( $ftp = Net::FTP->new( $S->{ $server }->{ 'Host' } ) ) { print 'Connected to ', $S->{ $server }->{ 'Host' }, $/; } elsif( $ftp = Net::FTP->new( $S->{ $server }->{ 'IP' } ) ) { print 'Connected to ', $S->{ $server }->{ 'IP' }, $/; } else { die 'Connect to ' . $S->{ $server }->{ 'Host' } . ' failed: ' . $@ +; } &FTP_login( { server => $server, handle => $ftp } ); return ( $ftp ); } sub FTP_login() { my $params = shift; my $server = $params->{'server'}; my $ftp = $params->{'handle'}; if( $ftp->login( $S->{ $server }->{ 'user' } , $S->{ $server }->{ 'pas +s' } ) ) { print 'Logged into ', $S->{ $server }->{ 'Host' }, ' whith user ', $S->{ $server }->{ 'user' }, $/; } else { die 'Login to ' . $S->{ $server }->{ 'Host' } . ' (' . $S->{ $server }->{ 'IP' } . ')' . ' failed for user ' . $S->{ $server }->{ 'user' } . ': ' . $ftp->message; } } sub FTP_get_file() { my $params = shift; my $s_name = $params->{'source_name'}; my $t_name = $params->{'target_name'} || $s_name; my $s_path = $params->{'source_path'} || ''; my $t_path = $params->{'target_path'} || ''; my $server = $params->{'server'}; my $ftp = &FTP_connect( { server => $server } ); my $count = 0; do { if( $ftp->get( $s_path . $s_name, $t_path . $t_name ) ) { $count = 6; print 'Got file ', ( $s_path . $s_name ), ' from ', $S->{ $server }->{ 'Host' }, ' saved at ', ( $t_path . $t_name ), $/; } else { if( {$ftp->message} =~ /No such file or directory/ ) { die 'Get ' . $s_path . $s_name . ' as ' . $t_path . $t_name . ' on ' . $server . ' failed: ' . $ftp->message; } if($count > 4) { die 'Get ' . $s_path . $s_name . ' as ' . $t_path . $t_name . ' on ' . $server . ' failed: ' . $ftp->message; } else { warn 'Get ' . $s_path . $s_name . ' as ' . $t_path . $t_name . ' on ' . $server . ' failed: ' . $ftp->message; $ftp = &FTP_connect( { server => $server } ); } $count ++; } } while($count < 6); $ftp->quit; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Net::FTP fail workaround
by VinsWorldcom (Prior) on Jun 03, 2015 at 13:18 UTC |