1

ここで非常に奇妙な問題があります。

Web サーバーには RESTfull Web サービスがありPython Paste、WPF .net アプリケーションは 2 秒ごとにサーバーに http POST 要求を行います。問題は、サーバーへの 2 回目の呼び出しで、要求がタイムアウトになることです。後で (4 番目または 5 番目と言う) リクエストが再び機能し、後で再びこの「タイムアウト」例外が発生することがあります。

IntelliTrace は、でブロックされた操作があったことを示していますws2_32.dll

WSACancelBlockingCall の呼び出しによってブロック操作が中断されました

IIS を使用して REST Web サーバーをシミュレートしたところasp.net、問題がなくなったので、Python サーバー構成である可能性があると思います。しかし、ブラウザ内からリクエストを行うと、Python Web サーバーは正常に動作します。

ただし、.net クライアント アプリケーションでさまざまなことを試しました。

  • ServicePoint を増やしましたDefaultConnectionLimit:

    ServicePointManager.DefaultConnectionLimit = 500;

  • サーバーへの新しいリクエスト用に新しいスレッドを作成し、リクエストが完了したら中止しました!

  • AppDomainリクエストの前に新しいを作成し、プロセスが完了したら明示的にアンロードしました!

  • 別の http 要求ヘッダーを試しました:connection=keep-alive, accept=*

上記のどれもうまくいかないようです!GetRequestStream()ただし、面白いのは、VS 2012の行にブレークポイントを設定すると、リクエストがタイムアウトせず、適切に機能することです。

リフレクションを使用して .net マネージ コードをデバッグすると、アンマネージrecvメソッドがws2_32.dll原因で操作がブロックされ、Web 要求がタイムアウトすることがわかりました。

C# コードは次のとおりです。

static void Main(string[] args)
{
    Task.Run(() =>
    {
        while (true)
        {
            Thread.Sleep(2000);
            Console.WriteLine(PostData());
        }
    });

    Console.ReadLine();
}

public static string PostData()
{
    try
    {
        var response = "";
        var httpRequest = WebRequest.CreateHttp("http://remote_address");
        httpRequest.ServicePoint.ConnectionLimit = 500;
        httpRequest.Method = "POST";
        httpRequest.ContentType = "application/x-www-form-urlencoded";
        httpRequest.Timeout = 5000;

        using (var writer = new StreamWriter(httpRequest.GetRequestStream()))
        {
            writer.Write("req=" + "[some parameters]");
        }

        using (WebResponse httpResponse = httpRequest.GetResponse())
        {
            using (var data = httpResponse.GetResponseStream())
            {
                StreamReader sr = new StreamReader(data, Encoding.UTF8);
                response = sr.ReadToEnd();
            }

            httpResponse.Close();
        }

        return response;
    }
    catch (WebException ex)
    {
        return "time out!";
    }
}

これを機能させるためにできることはあります

4

1 に答える 1

1

Expect100Continueヘッダーを無効にすることで問題を解決できました:

ServicePointManager.Expect100Continue = false;

HTTP 1.1プロトコルによれば、このヘッダーが送信されると、POST メソッドを使用するクライアント要求は、クライアントがポスト100-Continueされるデータを送信する必要があることを示す応答をサーバーから受信することを期待します。

このプロパティをtrue(.Net の既定の動作) に設定すると、最初の要求でデータが送信されません。100-Continue代わりに、このヘッダーは、正しく実装されている場合に応答する Web サーバーに送信されます。ただし、データを投稿しようとしているサーバーを含め、すべての Web サーバーがこれを正しく処理するわけではありません。を使用してヘッダーをスニッフィングしFiddlerたところ、コードがこのヘッダーを送信しているのに、送信していないことに気付きましたPython Paste!

于 2012-11-15T16:29:35.683 に答える