タイトル | : Net::FTPを使ったらどうですか? |
投稿日 | : 2012/02/27(Mon) 20:21 |
投稿者 | : おやじ |
> Connect to ***************
> 220 ************ FTP Server Ready
> USER *******
> 331 Password required for *******
> PASS *********
> 230 User ****** logged in
> TYPE I
> 200 Type set to I
> PORT ***, ***, *, **, ***, **
> C:\ffftp_local\ftpget.pl中断:応答コード0のため
現状のエラーは、単にPORTコマンド用文字列の作り方がおかしいからです。
カンマ区切りでアドレスとポートを書きますが、空白を入れては駄目です。
誤:$PortStr = sprintf("%d, %d, %d, %d, %d, %d", unpack("C4",$MyAddr),unpack("C2",pack("n",$MyPort)));
正:$PortStr = sprintf("%d,%d,%d,%d,%d,%d", unpack("C4",$MyAddr),unpack("C2",pack("n",$MyPort)));
それ以外も直さないと動かないと思いますが、これは自分で書いたのですか?
本来の目的は何なのでしょうか?
perlの勉強? ソケット通信の勉強? FTP通信の勉強?
単にFTPでCSVファイルがダウンロードできれば良いだけなら何もこんな難しいことしなくても良いのでは?
perlはいろいろなモジュールがあるので、それらを使えば簡単にできます。
例えば、今回のケースならNet::FTPモジュールです。以下で、ほぼ同じことができます。
下記の例でのFTPのモードはPassiveモードですが、PORTモードではないとまずい(元のソフトはこちらですが、こちらを使う意味がよくわかりません。)場合は、
「$ftp = Net::FTP->new($HostName, Passive => 1)」のところの「Passive => 1」を「Passive => 0」としてください。
----- ここから -----
#!/usr/bin/perl --
use warnings;
use Net::FTP;
$HostName = '***.***.***';
$User = '********';
$Pass = '********';
$Path = '/aaaaa/bbbbb/ccccc.csv';
# パスをディレクトリとファイル名に分ける
$Path =~ m|[^\\\/]+$|i;
$Dir = $`;
$File = $&;
print "Path:$Path\n";
print "File:$File\n";
print "Dir :$Dir\n";
$ftp = Net::FTP->new($HostName, Passive => 1)
|| die "Cannot connect to '$HostName': $!";
$ftp->login($User,$Pass)
|| die "Cannot login '$HostName:$User':" . $ftp->message;
if ( $Dir ne '' )
{
$ftp->cwd($Dir)
|| die "FTP command fail: " . $ftp->message;
}
$ftp->get($File)
|| die "FTP command fail: " . $ftp->message;
$ftp->quit;
----- ここまで -----