- ベストアンサー
FTP接続中かどうかを調べる
- vb.net 2005のシステムでtxtファイルを外部ホスティングサーバーに送りあげる際に、稀にftp接続でエラーが起きずにタスクが固まることがある。プロセスIDを取得する方法はわかるが、ftp接続中かどうかを判定する方法がわからない。どのように対処すべきか、また他の対処方法についても教えてほしい。
- vb.net 2005のシステムでtxtファイルを外部ホスティングサーバーに送る際に、稀にftp接続中にプロセスが固まることがある。ftp接続中かどうかを判定する方法と、固まったプロセスを強制終了する方法について教えてほしい。
- vb.net 2005のシステムでtxtファイルを外部ホスティングサーバーに送る際に、ftp接続中にプロセスが固まることがある。プロセスIDは取得できるが、ftp接続中かどうかを判定する方法がわからない。固まったプロセスをどのように終了すべきかを教えてほしい。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
すみません。.netのソースはわかりません。 即席で調べて見たのですが、補足されたソースのどこに問題があるのかはっきりわかりませんでした。 が、気づいたこととして、 ○If Int_Err = 3 Then の部分は、If Int_Err >= 3 Then のほうがいいのでは? Int_Errはどこでリセットしているのでしょう? ○「Streamを取得」=>「ファイルを開く」=>「Streamに書き込む」のどの時点でエラーが起きているのかわからないように思います。 「Streamを取得」したあとにエラーが起きているときには、reqStrm.Close() が実行されないまま、Try に戻っているのではないですか? ○Catch wex As System.Net.WebException だけしか見えませんが、他の例外処理はないのでしょうか? これ以外のエラーが発生した場合にどうなるのでしょう? ○3回のリトライが失敗しても UpRoad = True にしていますが、その後の処理はどうしているのでしょうか? 私のFTPソフトはVB6で作りました。.netのコードについては評価できません。 まとはずれでしたら、ご容赦ください。
その他の回答 (4)
- makohyu
- ベストアンサー率60% (57/94)
実は、私もFTPソフトを作ってお客さんに使ってもらっているのですが、今回の問題を解決できるような専門的なことはわかりません。 その上で、わかる範囲でお答えしますので、間違っていたらご容赦ください。 > (1)接続しっぱなしになっていた場合、システムに与える影響はどのようなものですか? > メモリを独占してしまう可能性があるってことですか? メモリではなく、接続したあとに操作を何もしなかったり、大量のデータを送信したりすると、サーバー側で切断する場合があるので、クライアント側でそれを検知できない場合、今回のような状態になる可能性があります。 それに専用サーバーでない場合、同じサーバーに同居している人に迷惑がかかることもあるのではないでしょうか。。。 今回の場合、他の同居人とFTP操作がかぶったせいかもしれませんし、メンテナンスが入っていたかもしれませんね。。。 送信データがそれほど大きくない場合には、送信するデータ単位に「接続」=>「送信」=>「切断」を確実に行うことで、そのような危険がなくなります。 パッシブモードで接続していれば、「接続」の段階でエラーになる可能性も少なくなるでしょう。 パッシブモードが使えないのであれば、失敗時に原因を確定して問題がなければリトライするようにしたらどうでしょうか? (そうすると、システムの構造が大分変わってしまうかもしれません。) > (2)「エラーとはならずに、固まった状態で・・・」という状態になってしまった原因の解明についてですが、現在ログをとったり、エラーの再現を試みたりしていますが解明できておりません。 エラー時の処理を点検してみてください。 どこかで、エラー処理を省略していませんか? > 今後の作業の進め方として、一時的な対処方法「該当exeのプロセスIDが一定時間変化がなく・・・」をとった上で、引き続き監視し、原因が解明された時点で根本的に対処しようと考えています。 アップロードするプログラムでは「接続」時にハンドルを取得しているはずですが、取得後に問題が発生していれば、このハンドルを開放してやらなければなりません。これが、「切断」です。 プロセスIDで強制終了した場合、サーバー側には問題はありませんが、OSによってはメモリ管理がおかしくなって重大な障害を引き起こす可能性もあるのではないでしょうか? > 一人で開発するのははじめてです。 > アプローチのしかたが間違ってるのか?正しいのか不安です。 > 何かアドバイスを頂ければと思います。 間違ってるかどうかは、私には判断できません。 アドバイスできることがあるとすれば、「決め付けをせず、自由な気持ちで正面から向き合うこと」です。 自由な心でいることが、ひらめきや集中力を引き出す方法だと思います。 お一人で大変だと思いますが、あきらめずにやってください!
補足
何度も申し訳ありません(><) とても感謝しております。 以下のソースはftp接続部分になります。 For s = 0 To 2 ' アップロードするファイル() Dim upFile As String = "C:\HighwayMail\SendData\Data\" & Flnm 'アップロード先のURI Dim u As New Uri(ftpad & "/data/" & Flnm) 'FtpWebRequestの作成 Dim ftpReq As System.Net.FtpWebRequest = _ CType(System.Net.WebRequest.Create(u), System.Net.FtpWebRequest) 'ログインユーザー名とパスワードを設定 ftpReq.Credentials = New System.Net.NetworkCredential(usernm, pass) 'MethodにWebRequestMethods.Ftp.UploadFile("STOR")を設定 ftpReq.Method = System.Net.WebRequestMethods.Ftp.UploadFile '要求の完了後に接続を閉じる ftpReq.KeepAlive = False 'ASCIIモードで転送する ftpReq.UseBinary = False 'PASVモードを無効にする ftpReq.UsePassive = False Try 'ファイルをアップロードするためのStreamを取得 Dim reqStrm As System.IO.Stream = ftpReq.GetRequestStream() 'アップロードするファイルを開く Dim fs As New System.IO.FileStream( _ upFile, System.IO.FileMode.Open, System.IO.FileAccess.Read) 'アップロードStreamに書き込む Dim buffer(1023) As Byte While True Dim readSize As Integer = fs.Read(buffer, 0, buffer.Length) If readSize = 0 Then Exit While End If reqStrm.Write(buffer, 0, readSize) End While fs.Close() reqStrm.Close() UpRoad = False Exit For Catch wex As System.Net.WebException Dim Err As String = wex.Status If Err = "2" Then UpRoad = True Exit For Else Int_Err = Int_Err + 1 If Int_Err = 3 Then System.IO.File.WriteAllText("C:\UL.log", wex.ToString) UpRoad = True Exit For Else Exit Try '10秒間(10000ミリ秒)停止する System.Threading.Thread.Sleep(10000) End If End If End Try Next End Function 補足すると接続に失敗したときにmakohyuさんがアドバイスされたようにリトライをかけています。しかし、無限にリトライをかけるのは怖く感じたために3回までかけています。 もし、3回以上失敗した場合は、エラーメールをシステム管理者に送るようにしています。 質問のメールの遅延が起こったとき、エラーメールは配信されていません。なので「エラーとはならずに、固まった状態で・・・」という可能性が大きいのではないかと思っています。 エラー処理部分について、何かおかしい部分がありましたらご指摘頂ければと思いました。 忙しい中、本当に申しわけありません。
- makohyu
- ベストアンサー率60% (57/94)
補足を拝見しました。 ご質問の中の「エラーとはならずに、固まった状態で・・・」という状態になってしまった原因の解明と対処が本筋ではないかと思われます。 一時的な対処法として、「該当exeのプロセスIDが一定時間変化がなく、かつftp接続中ではないときにexeを強制終了する仕組み」を作ったとしても、本来の目的である業務(メール配信)が不完全であることは変わりません。 ご質問に対する回答になっていないので、恐縮なのですが。。。 私のご質問に対する回答としては、#1です。
補足
丁寧な回答ありがとうございます。 こちらの方から2点質問させてください。 (1)接続しっぱなしになっていた場合、システムに与える影響はどのようなものですか? メモリを独占してしまう可能性があるってことですか? (2)「エラーとはならずに、固まった状態で・・・」という状態になってしまった原因の解明についてですが、現在ログをとったり、エラーの再現を試みたりしていますが解明できておりません。 今後の作業の進め方として、一時的な対処方法「該当exeのプロセスIDが一定時間変化がなく・・・」をとった上で、引き続き監視し、原因が解明された時点で根本的に対処しようと考えています。 一人で開発するのははじめてです。 アプローチのしかたが間違ってるのか?正しいのか不安です。 何かアドバイスを頂ければと思います。 よろしくお願いします。
- makohyu
- ベストアンサー率60% (57/94)
> 切断したらというのは、txtファイルの送り上げが完了したらという意味でしょうか? 現在開発用に使っているPCがメンテ中なので、過去のソースを見ながら詳しく説明ができないのですが、安全にFTP転送を行うには、「接続の確立」=>「転送などの作業(txtファイルの送り上げ)」=>「切断(クローズ)」と連続した処理として行う必要があります。 「切断」としたのは、この一連の作業が終了したらということです。 ちなみに、途中でクライアント側で別の作業ができるような構造になっていると、サーバー側でかってに切断してしまうなどの不具合が起こったりします。 サーバーによっては復旧に手間取る場合もあります。 > 接続モードと、このような事象との間に何か関係性はあるのでしょうか? パッシブモードでの接続は、「整理券」をもらって列に並んで買い物をするようなもので、安全なFTP転送をおこなうには必要なことですが、お使いのサーバーで許可されていないのでしたら、しょうがないですね。 ご質問のような問題に対して、「ftp接続中かどうかを判定」して対処するのではなく、問題の根本の原因を明らかにして対処したほうがいいように思います。 「送りあげるシステム」とは、どのようなものでしょうか? VBからはどのように使っているのですか? このシステムに問題があるか、このシステムの使い方に問題があるのか、それともサーバーに問題があるのかを調べてみたらどうでしょうか。。。 原因として考えられる範囲が広すぎるので、もう少し情報を補足してください。
補足
返信ありがとうございます。 送り上げるシステムをはメール送信システムの一部になります。 まず、監視.exeにより任意のファルダにtxtファイルの存在を常に監視します。txtファイルの存在を確認したら、txtファイル送り上げシステムのexe(仮にアップロード.exeとします)を起動し、外部ホスティングサーバーにtxtファイルをアップロードします。外部ホスティングサーバー内ではメール送信.pl(perl)が常駐しており、txtがアップロードされたのを確認したらtxtファイルを読み、メールを送信し、メール送信履歴を出力しています。 アップロード.exeはtxtファイルをアップロードした後にダウンロード.exeを起動し、メールの送信履歴をダウンロードをします。 メール送信システムは、監視(常駐)→アップロード.exe→ダウンロード.exeという流れでなっていますので、アップロード.exeとダウンロード.exeが終了するのを待って、監視.exeは次の処理をしようとします。 このようなシステムで一ヶ月近く順調に動いてなのですが、ある一回だけメールの遅延が発生しました。 アップロードの箇所でログを取っていなかったために、原因がつかめていません。 推測にすぎないのですが、ftpをアップロードまたは、ダウンロードした際に最初の質問に書いたような事象が起こったのが遅延の原因ではないかと思い、対処しようとしています。 現在はアップロード箇所でログを取得していますが、問題はないようです。
- makohyu
- ベストアンサー率60% (57/94)
ファイルにプロセスIDと接続開始時間を記録して、切断したら削除するようにしたらどうでしょうか? 接続するときにパッシブモードで接続してますか? また、接続しっぱなしにしていませんか?
お礼
回答ありがとうございます。 質問があります。 >切断したら削除するように 切断したらというのは、txtファイルの送り上げが完了したらという意味でしょうか? 接続については、アクティブで行っています。 (パッシブでは接続が許可されてないからです。) 接続しっぱなしにはしていません。 接続モードと、このような事象との間に何か関係性はあるのでしょうか? ご教授ください。
補足
回答ありがとうございます。 Streamを取得」したあとにエラーが起きているときには、reqStrm.Close() が実行されないまま、Try に戻っているのではないですか? とのご指摘。全くその通りです。 サーバー側で切断された場合を想定してなかったために、最初の質問のような現象がおきた可能性があります。 しつこく質問してしまって本当に申し訳ありません。 ありがとうございました。