PHP を使用して (Windows で実行されている) FTP サーバーをマップする必要があったため、基本的に FTP のフォルダー構造をナビゲートし、その中のすべてを一覧表示し、サブフォルダーに遭遇すると再帰的に自分自身を呼び出す関数を作成しました。
私の開発環境ではすべてがうまくいきましたが、すべてをクライアントのインフラストラクチャに移行すると、事態は悪化しました。彼らの FTP サーバーは 30GB のデータを保持しているため (多くのファイルは 100MB を超えるため、多くのファイルがありますが、期待するほど多くはありません)、「遅い」と予想していましたが、90 秒から 120 秒はかなり長いように見えました。
そのため、tcpdump を使用して調査を行ったところ、特定の時点ですべての要求が少なくとも 60 秒間停止するため、FTP サーバーにある種のフラッド防止機能があることが完全にわかります。この動作は、 lftp を使用してサーバーを再帰的にマップしようとした場合にも発生します。
パッシブが次のエラーをスローしたため、現在アクティブ モードを使用しています。
Warning: ftp_rawlist() [function.ftp-rawlist]: php_connect_nonb() failed: Operation now in progress (115) in /home/user/public_html/sync.php on line 35
35 行目は、現在のディレクトリの ftp_rawlist を参照しています。
役立つかどうかはわかりませんが、とにかく使用しているコードは次のとおりです。
function ftp_get_recursive_paths($conn, $path, $root, $max_level = 0) {
$files = array();
$contents = ftp_rawlist($conn, $path);
if(is_array($contents)) {
foreach($contents as $line) {
(...) Parsing the results (...)
if ((strpos($f, ".DS_Store") === false) && (strpos($f, ".dropbox") === false) && (strpos($f, "Thumbs.db") === false)) {
if(!strpos($f, '.')) {
$init = microtime(true);
$files[$f] = (object) array('name' => $f, 'date' => $date, 'path' => $path . $f, 'content' => ftp_get_recursive_paths($conn, $path . $f, $path));
$end = microtime(true);
echo '<p> Folder ' . $path . $f . ' scanned in '. ($end - $init), ' seconds. </p>';
}
else {
$files[] = (object) array('name' => $f, 'date' => $date, 'path' => $path . $f);
}
}
}
}
return $files;
}
この洪水防止のことをどのように防ぐことができるか知っている人はいますか? ファイアウォールですか?クライアントのサーバーでの何らかの構成?
クライアントが Windows で Filezilla Server を使用していることを確認できます。