- - PR -
FTP受信中にエラー
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-07-06 23:11
どのくらい困っているのかわかりませんが、 keepaliveしないようにすれば動くようですし、 仕方ない、と言えるならそれでいいですね。 HTTPWebRequestもFTPWebRequestも高位のクラスですからかなり癖があり、 ネットワークやサーバー環境によっては動かなくなります。 ですが、いろいろ設定する方法があり、 問題発生の状況によっては対応することができます。 相手が出すエラーでも対応する方法もありますし、 エラーが出ても接続を切らずにうまく切り抜ける方法もあります それほど必死じゃないなら、 もうここに投稿せずにスルーすればOK。 どうしても何とかしなければならないなら、 状況を詳しく説明すれば、 私や誰かが解決する方法を知っているかもしれません、ね。 | ||||||||||||||||
|
投稿日時: 2007-07-09 12:20
れいさん、こんにちは
申し訳ございませんでした。 長くなりますが、コード部分を書きます。 ===== ループ部分 ====== date = 前回取得した日付; do { string remote_path = "ftp://192.168.0.1/down/" + date.toString("yyyyMMdd") + "*.CSV"; string strbuf = GetDirectory(remote_path,"ftpid","ftppass"); string[] strFiles = strbuf.Replace("\r\n", "\n").Split('\n'); foreach (string s in strFiles) { if (s == "") break; FtpDownload("ftp://192.168.0.1/down/" + s, "c:\\down\\" + s, "ftpid", "ftppass"); } date = date.AddDays(1); } while (date <= DateTime.Today); ===== ディレクトリサーチ部分 ====== private string GetDirectory(string uri, string id, string pass) { string strDirectory = null; FtpWebRequest req = (FtpWebRequest)WebRequest.Create(uri); req.Credentials = new NetworkCredential(id,pass); req.KeepAlive = false; // これを入れてエラーが出なくなりました req.Method = WebRequestMethods.Ftp.ListDirectory; FtpWebResponse res; try { res = (FtpWebResponse)req.GetResponse(); } catch (WebException ex) //←←ここでエラーになります。 { MessageBox.Show(ex.Message, ex.Status.ToString()); return ""; } Stream resStream = null; StreamReader reader = null; try { resStream = res.GetResponseStream(); reader = new StreamReader(resStream, System.Text.Encoding.GetEncoding("SHIFT_JIS")); if (reader != null) { strDirectory = reader.ReadToEnd(); } } catch (WebException ex) { MessageBox.Show(ex.Message); } finally { res.Close(); reader.Close(); resStream.Close(); } return strDirectory; } ===== ダウンロード部分 ====== private bool FtpDownload(string uri, string localfile, string id, string pass) { FtpWebRequest req = (FtpWebRequest)WebRequest.Create(uri); req.Credentials = new NetworkCredential(id, pass); req.Method = WebRequestMethods.Ftp.DownloadFile; FtpWebResponse res; try { res = (FtpWebResponse)req.GetResponse(); } catch (WebException ex) { MessageBox.Show(ex.Message + "\n" + localfile); return false; } Stream resStream = null; StreamReader reader = null; StreamWriter writer = null; try { resStream = res.GetResponseStream(); reader = new StreamReader(resStream,Encoding.GetEncoding("SHIFT-JIS")); if (reader != null) { writer = new StreamWriter(localfile, false, Encoding.GetEncoding("SHIFT-JIS")); writer.Write(reader.ReadToEnd()); } } catch (WebException ex) { MessageBox.Show(ex.Message + "\n" + localfile); return false; } finally { reader.Close(); res.Close(); writer.Close(); resStream.Close(); } return true; } ===== ここまで ======
ある日付のファイル量には関係なく、 読み込む日付の期間が長いと途中のディレクトリサーチ時点でエラーになります。
書き方が悪くて申し訳ありません。 エラーになった日付指定で1回だけの処理で読むとエラーにならないです。 また、FTPツール(FFFTP)で試すと、エラーにはなりません。 エラー的には、keepaliveで出なくなったのですが、 根本的な理由が分からない為、このまま利用していいのか 迷っております。 れいさん、皆さん どうかアドバイスをよろしくお願いします。 [ メッセージ編集済み 編集者: のん吉 編集日時 2007-07-09 12:21 ] | ||||||||||||||||
|
投稿日時: 2007-07-09 13:43
おそらくは認証の問題です。 接続先サーバーもネットワーク構成もわかりませんので、 確実にこれで治ります、とは言えませんが、 少なくともNetworkCredentialの使い方が間違っています。 FTPWebRequestやHTTPWebRequestは、 NetworkCredentialを毎回初期化して用いると、 前回の要求時のCredentialを忘れてしまう場合があります。 その場合、以前の要求で用いたのと同じユーザー名でも再認証を試みます。 HTTPの場合は要求志向なのであまり問題ありませんが、 FTPは接続ごとに認証を管理しているので、 再認証を試みるとエラーになります。 ループ開始時にNetworkCredentialインスタンスを一つ作成し、 それをすべてのFTPWebRequestで共有するようにするのが正しい方法です。 それでだめな場合は… パケットキャプチャしないと私にはわかりません。 | ||||||||||||||||
|
投稿日時: 2007-07-09 14:36
れいさん
うまく動作致しました、ありがとうございます。 れいさんのおっしゃるとおり、認証の部分を
で、実行したところ問題が解決しました。
大変、参考になりました。 しかし、このような情報はどうやって調べているのでしょうか? 結構、調べたつもりでしたが。。。 皆さん、本当にありがとうございました。 | ||||||||||||||||
|
投稿日時: 2007-07-09 15:40
>しかし、このような情報はどうやって調べているのでしょうか?
>結構、調べたつもりでしたが。。。 えーっと。 調べるというのはWebやMSDNですか? あれこれコーディングはしましたか? 今回の件は、以前WebRequestについて調べた際、 私が実際にコーディングしてあれこれ試したときの知識です。 誰にも言ってませんし、Webに載せてもいないので、 Webに載っていなくてもおかしくはありません。 FTPの仕組みとWebRequestの仕組みをよく理解して、 コーディングしてパケットキャプチャすれば 今回の問題は調べられます。 それほど難しくはありません。 ご参考までに、 問題が発生した場合の 私の処理アルゴリズムを載せておきます。
無限ループにならないように 腹減りタイマーで処理時間を計測する必要があります。 | ||||||||||||||||
|
投稿日時: 2007-07-09 16:16
れいさん、ありがとうございます。
まだまだ、初心者なので調べ方を調べるのに 時間を費やしている段階です。。。 今の所、Web(日本語)とMSDNで調べながら コーディングして動作確認程度で、WebRequestの仕組み まで手が出ていませんでいた。 それなのに、調べたつもりなんて言ってしまいました。。。 今後は、れいさんのアルゴリズムを参考に 無限ループに陥ったら、書き込みさせて頂きます。 (英語はわかりませんが。。。) れいさん、本当にありがとうございました。 |