1

リクエストを再試行した後、POST データが何らかの形で失われるという問題に直面しました。以下のコードサンプル。( request.timeout = 1 は、以下のコードに示されている動作を再現するためのテスト目的で設定されていることに注意してください):

//post_data_final getting

private void request_3()
    {
        for(int i=1; i<=5; i++)
        {
            byte[] byteArray = Encoding.ASCII.GetBytes(post_data_final);
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(site_URI);
            request.Method = "POST";
            //some headers info
            request.Timeout = 1;
            request.ContentLength = byteArray.Length;
            using (Stream os = request.GetRequestStream())
            {
                os.Write(byteArray, 0, byteArray.Length);
            }
            try
            {
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                //some code about response
            }
            catch (WebException wex) 
            {
                if (wex.Status == WebExceptionStatus.Timeout)
                {
                    continue;
                }
                //some additional checks
            }
        }
    }

魔法は、最初のリクエスト (リクエスト タイムアウト エラーまで) がうまくいくことです。以降のリクエストはPOST データなしで行われますが、コンテンツの長さは適切にカウントされます (つまり、前のリクエストと同じままです)。


更新しました:

  1. post_data_final の取得は別の関数です。これは (byteArray を除いて) 使用されないか、request_3() 関数で変更されます。
  2. for ループに入ってタイムアウト例外が発生していなければ、リクエストは正常に機能します。したがって、リクエストを for ループに入れると、特定の数の有効なリクエストが実行されます。タイムアウト例外が発生するとすぐに、次のリクエストは POST データなしになります。
  3. ソースコードは、再帰は悪い考えだと思う人のために編集されています。編集したコードはまだ機能しません。

どんな提案でも大歓迎です

4

2 に答える 2

0

この問題は、Wireshark の類似物である Fiddler2 (つまり、トラフィック ツールのインターセプト) を使用したことが原因でした。

要求されたサイトは https プロトコルを使用しています。デバッグの目的で、Fiddler2 と Fiddler2 証明書をインストールして、すべての受信応答と送信応答を確認できるようにしました。Fiddler2 をオフにしてコンソールに追加のログを追加したときに、いくつかの魔法の理由で、リクエストが有効であるように見えることがわかりました (つまり、最初のリクエストの後、POST 本文データがまだ存在します)。

したがって、タイムアウト例外が発生している間は、上記の Fiddler2 コードは機能しません。Fiddler2 がなくても、同じ状況で同じコードを使用すると、すべてが正常に機能します。

私はFiddler2を深く掘り下げませんでしたが、問題はVS2010とエラーコードの内部プロキシの互換性にのみあるようです(「更新」領域の下のポイント2を使用することを考慮して(Fiddler2もそこで使用されました)成功するコード (つまり 2xx - 3xx) は問題なく動作しました)

これに注目してくれてありがとう。

于 2013-11-11T18:25:28.253 に答える
0

コードに問題が見つからないので、コメントに記載されているようにモードの詳細を提供してください。

private void request_3()
{
    bool sendData = true;
    int numberOfTimeOuts = 0;

    // The follwing only needs to be done only once, unless you alter post_data_final after each timeout.
    byte[] dataToSend = Encoding.ASCII.GetBytes(post_data_final);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(site_URI);
    using (Stream outputStream = request.GetRequestStream())
        outputStream.Write(dataToSend, 0, dataToSend.Length);



    // request.TimeOut = 1000 * 15; would mean 15 Seconds.

    while(sendData && numberOfTimeOuts < MAX_NUMBER_OF_TIMEOUTS)
    {
         try
         {
             HttpWebResponse response = (HttpWebResponse)request.GetResponse();
             if(response != null)
                 processResponse(response);
             else
             {
                 //You should handle this case aswell.
             }

             sendData = false;
         }
         catch(WebException wex)
         {
             if (wex.Status == WebExceptionStatus.Timeout)
                 numberOfTimeOuts++;
             else
                 throw;
         }
    }
}
于 2013-11-11T17:18:50.460 に答える