サーバーにファイルをアップロード(PUT)しようとしているのですが
うまくいきません。
次のようなソースです。
何が悪いのか診断してもらえないでしょうか?
※補足
・FFFTPでは、PASVモード有効、ポート番号21でGETもPUTも成功しているので、
FTPの設定の問題ではないと思います。
・$ftp->pwd()すると、cwdで移動したパスをちゃんと取ってくるので、
ログインや cwdは成功しているようです。
・特に、$ftp->putでパソコン上のファイルのパスを指定する方法がよくわかりません。
use Net::FTP;
$FtpHostName = "hogehoge.com";
$FtpDataPath = "/home/hogehoge/www/sub";
$FtpUserName = "myname";
$FtpPassword = "letmein";
$datafile = "C:\\temp\\test.txt";
$ftp = Net::FTP->new( $FtpHostName );
$ftp -> login( $FtpUserName, $FtpPassword );
$ftp -> pasv();
$ftp -> port( 21 );
$ftp -> ascii();
$ftp -> cwd( $FtpDataPath );
$ftp -> put( $datafile ) or
die "PUT FAILED";
$ftp -> quit();
よろしくお願いします。
「$ftp -> port( 21 );」の行を削除して試してみてください。
このメソッドは、サーバーの21番ポートに接続する事を指定するものではなく、クライアントPCのIPアドレスと待ち受けるポートを送信するもののようです。
http://x68000.q-e-d.net/~68user/net/ftp-4.html
・「ポート番号の伝達」より
・PORT … ポート番号を送信 (Active モード)
データコネクションの確立の際、FTP サーバ側から FTP クライアント側に接続するよう伝える。 FTP クライアントが IP アドレス 10.0.0.1 で動いており、ポート 5000 番を listen しているなら、
PORT 10,0,0,1,19,136
200 PORT command successful.
と送信する (5000=19×256+136)。 その後 FTP クライアントが LIST やRETR コマンドを送信すると、 FTP サーバ側が 10.0.0.1 のポート 5000 に接続し、データの送受信が始まる。
※次のように「$ftp->message」でコマンド実行で返されたメッセージを確認してみてください。
$ftp->pasv(); print $ftp->message . "<br>\r\n";
次のような形式でIPアドレスとポート番号が返されると思います。
Entering Passive Mode (***,***,***,***,242,90).
※上記の場合、242×256+90=62042番ポート
※Activeモードで接続する場合、「$ftp->port()」と何も指定しないで実行してみてください。(「$ftp->port(***,***,***,***,xxx,xx)」と自分のPCのIPとポート番号を指定しても接続できると思いますが、未確認です。)
※Passiveモードで接続するのでしたら、portを実行する必要はありません。
ActiveモードとPassiveモードの違いは、次のページも確認しておくとより理解できると思います。
http://x68000.q-e-d.net/~68user/net/ftp-3.html
※(1)から読んでもいいと思います
「Active モード」というもので、データコネクションの確立の際、「FTP サーバ側が能動的に FTP クライアント側に接続する」という動作になります。
一方、「Passive モード」というものがあります。このモードでは、「FTP サーバ側が受け手となり、FTP クライアントからの接続を待つ」という動作になります。つまり、FTP クライアントは、 bind・listen・accept などのサーバ的な動作をする必要がなくなるのです。
あるいは、オプションで次のように指定しても、すべての転送がPassiveモードになるようです。
$ftp = Net::FTP->new($FtpHostName, Passive => 1);
http://perldoc.jp/docs/modules/libnet-1.12/Net/FTP.pod
Passive - 0以外の値を設定すると、全てのデータ転送はパッシブモードを使って行われます。いくつかのダム(dumb)サーバーといくつかのファイアウォールの設定を除けば、通常、必要とされません。これは環境変数FTP_PASSIVEによって設定することもできます。
ファイアーウォール機能でPerl.exeを拒否していないか確認してみてください。(一応、Windowsのファイアーウォール機能の設定も・・・)
ローカル環境に設置したスクリプトを実行して、外部のFTPサーバーに接続したいのだと思っていました・・・
他の人にファイルをアップロードしてもらうのが目的でしたら、フォームを利用してアップロードするようにするといいかもしれません。
たくさんのポイントといるかをありがとうございました。m(__)m
レンタルサーバーに設置したCGIを使って
ローカルPCのファイルをサーバーにアップロードしようとしていました。
質問が説明不足で申し訳ありませんでした。
回答とてもありがたかったです。
お恥ずかしい話、
今までは PASVモードもおまじないのようにON/OFFしていただけで
意味もわかっておらず、
今回初めて理解できました。
FTPの仕組みがいろいろわかったので、今後の役に立つと思います。
こちらこそありがとうございました。