- PR -

ネットワークが一時切断された場合のHttpWebRequestでの再接続

1
投稿者投稿内容
pista
会議室デビュー日: 2007/12/07
投稿数: 5
投稿日時: 2007-12-07 14:49
現在、HttpWebRequestを使用してhtmlをダウンロードするプログラムを作成しています。
htmlをダウンロード中に、ネットワークが一時的に切断された場合、
WebExceptionを拾って、3秒待機してから、htmlを最初からダウンロードしたいのですが、
ナゾの障害で困っています。

以下のメソッドで指定したURLからhtmlを取得しています。
太字部分で示したHttpWebRequestをwhileの中で定義すれば期待通りの結果が得られるのですが、
外側で定義すると、「リモート サーバーに接続できません。」や「要求は中止されました: 接続が予期せずに閉じられました」
等のエラーが出てダメです。

どなたか、原因が分かる方がいましたら教えてください。

動作確認は、プログラムを実行している最中にローカルで、ファイヤーウォールをOnにしてネットワークを
切断し、数秒後にファイヤーウォールをOffにして行っています。

コード:
private string GetHtml(string url) {
            int errorCount = 0; // エラーの発生回数
            int timebase = 1;   // エラー発生時の待ち時間
            string log = "";

/*

            /////////  ここにHttpWebRequestの定義を書くとエラーが出る
            /////////  whileの中に入れるとちゃんと動く
            //HttpWebRequestの作成
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            //文字コード(EUC)を指定する
            System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
            // タイムアウト設定 
            req.ReadWriteTimeout = 5 * 1000;
            req.Timeout = 5 * 1000;
            // 最大同時接続数
            ServicePointManager.DefaultConnectionLimit = 10;
            //////////////////////////////////////////////////////////////////////

*/

            while (true) {

                ////////////////////////  whileの中ではちゃんと動く ///////////////////
                //HttpWebRequestの作成
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
                //文字コード(EUC)を指定する
                System.Text.Encoding enc = System.Text.Encoding.GetEncoding("shift_jis");
                // タイムアウト設定 
                req.ReadWriteTimeout = 5 * 1000;
                req.Timeout = 5 * 1000;
                // 最大同時接続数
                ServicePointManager.DefaultConnectionLimit = 10;
                //////////////////////////////////////////////////////////////////////

                System.IO.Stream st = null;
                System.IO.StreamReader sr = null;
                HttpWebResponse res = null;
                try {
                    //応答データを受信するためのStreamを取得
                    res = (HttpWebResponse)req.GetResponse();
                    st = res.GetResponseStream();
                    if(st != null) sr = new System.IO.StreamReader(st, enc);
                    //受信して表示
                    string html = sr.ReadToEnd();
                    return html;
                }
                catch(WebException e) {
                    if (++errorCount >= 5) { // 4回まで再接続する
                        throw (e);
                    }
                    System.Threading.Thread.Sleep(3000);
                }
                finally { //Closeの処理はここで全て行う
                    if(sr != null) sr.Close();
                    if(st != null) st.Close();
                    if(res != null) res.Close();

                }

            }
}

れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-12-07 15:04
引用:

pistaさんの書き込み (2007-12-07 14:49) より:
太字部分で示したHttpWebRequestをwhileの中で定義すれば期待通りの結果が得られるのですが、
外側で定義すると、「リモート サーバーに接続できません。」や「要求は中止されました: 接続が予期せずに閉じられました」
等のエラーが出てダメです。



HttpWebRequestはエラーが起きたときには再利用できません。
もう一回作り直さなければダメです。
pista
会議室デビュー日: 2007/12/07
投稿数: 5
投稿日時: 2007-12-07 15:18
れいぬしさん、ご返信ありがとうございます。

引用:

HttpWebRequestはエラーが起きたときには再利用できません。
もう一回作り直さなければダメです。


そうなんですか、全然知りませんでした。じゃあwhileの中に入れておかなきゃいけませんね。
もう一つお聞きしたいのですが、このような情報は、msdn等で公開しているのでしょうか。
ソースがあれば教えてくれませんか。
自分もレベルアップしたいので、恐れ入りますがよろしくお願いいたします。




れい
ぬし
会議室デビュー日: 2005/11/01
投稿数: 346
投稿日時: 2007-12-07 15:47
引用:

pistaさんの書き込み (2007-12-07 15:18) より:
れいぬしさん、ご返信ありがとうございます。



私は「れい」です。
「ぬし」は@ITが勝手につけてるだけで、かわいくないから嫌いです。

引用:

もう一つお聞きしたいのですが、このような情報は、msdn等で公開しているのでしょうか。


このような情報は全てmsdnに載っているというわけではありません。
そんなことをしたらmsdnを作るのに莫大な時間がかかってしまいますし、
情報が多すぎて使えないものになります。

引用:

ソースがあれば教えてくれませんか。


今回の件がmsdnに載っているかどうか、私は知りません。
Webで見かけたこともありません。
自分で試してそうだったから、というのがソースです。

自分で試したり、Webで情報を仕入れたり、
自分なりの情報源で調べるものだと思います。
pista
会議室デビュー日: 2007/12/07
投稿数: 5
投稿日時: 2007-12-07 16:24
引用:

私は「れい」です。
「ぬし」は@ITが勝手につけてるだけで、かわいくないから嫌いです。


そうでしたか(笑)、失礼しました。どうやって小さい文字を入力したんだろう?と思いました。

引用:

このような情報は全てmsdnに載っているというわけではありません。
そんなことをしたらmsdnを作るのに莫大な時間がかかってしまいますし、
情報が多すぎて使えないものになります。


なるほど。

引用:

今回の件がmsdnに載っているかどうか、私は知りません。
Webで見かけたこともありません。
自分で試してそうだったから、というのがソースです。

自分で試したり、Webで情報を仕入れたり、
自分なりの情報源で調べるものだと思います。


そうですか。自分なりの情報源を作る事が大事なんですね。
私もこれからがんばります。
れいさん、ありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)