サードパーティのサーバーに接続しています。私は今、同じリモートユーザーからの8つの接続を許可していることを知っています. ただし、接続制限を引き上げるか引き下げるかはわかりません。だから私は自分のアプリに動的に見つけてもらいたいのです。これどうやってするの?
私はC#、MSVS 2008を使用しています
私は、C# を動作させてくれる人のために報奨金を始めました。誰も答えてくれなければベストアンサーにします。
私はこれを行うのが非常に難しく、いくつかの試みに失敗しました:(
サードパーティのサーバーに接続しています。私は今、同じリモートユーザーからの8つの接続を許可していることを知っています. ただし、接続制限を引き上げるか引き下げるかはわかりません。だから私は自分のアプリに動的に見つけてもらいたいのです。これどうやってするの?
私は、C# を動作させてくれる人のために報奨金を始めました。誰も答えてくれなければベストアンサーにします。
私はこれを行うのが非常に難しく、いくつかの試みに失敗しました:(
これは、サーバーがデフォルトでクライアントに提供する情報ではありません。知る唯一の方法は、失敗するまで接続を開き続けるか (悪い考えです)、サーバーの所有者に、この情報を返すポーリング可能なサービスを提供するよう依頼することです。
編集:この質問についてもう少し考えた後、実際の精度で「調査」することでこれを判断できるかどうかわかりません。503 Server Busy
接続制限に達したときにサーバーが返された場合 (最初の提案を行ったときに発生すると想定していました)、テストが容易になります。ただし、通常、サーバーが接続制限を超えると、新しい接続が利用可能になるまで応答しません。クライアントは応答を待つだけです。接続制限に達したために応答するのに 10 秒かかったサーバーと、その他の理由で応答するのに 10 秒かかったサーバーを区別する難しい方法はありません。
さらに、この方法でテストを試みたとしても、サーバーへのリクエストは、作成した最初の接続 (および後続のすべての接続) が n 番目のリクエストのときにまだ開いていることを確認するのに十分な時間、開いたままにする必要があります。タイムアウトします。これは、返るのに非常に長い時間がかかるサービス (実行時間の長いプロセスまたは Thread.Sleep(); のいずれか) を呼び出すことを意味します。または、不便なほど大きなファイルをダウンロードします。どちらのアプローチも、せいぜい非常に非効率的です。
貧乏人の方法は、netstat にシェルし、stdout を取得して、それを調べることです。他のコンピューターへの現在の接続のスナップショットを提供します。これにより、特定のサーバーに接続した回数を判断できます。
-ドン
あなたの場合のより良い考えは、おそらくあまり気にしないことです。接続を 1 つずつ開いて、アプリケーションのパフォーマンスを調べてみました。別の接続を開くことでパフォーマンスが向上する限り、新しい接続を開き続けます。パフォーマンスの上昇が止まると、最適な接続数にかなり近づいています。
私はこの賞金を受け取ります。なぜこれをやりたいのか、なぜ誰かが8つの接続を許可するのか正確にはわかりません.
1999 年 (RFC 2616) で定義された「永続的な接続を使用するクライアントは、特定のサーバーに対して維持する同時接続の数を制限する必要があります。シングルユーザー クライアントは、サーバーまたはプロキシとの接続を 2 つ以上維持するべきではありません。プロキシは、別のサーバーまたはプロキシに対して最大 2*N の接続を使用する必要があります。ここで、N は同時にアクティブなユーザーの数です。これらのガイドラインは、HTTP 応答時間を改善し、輻輳を回避することを目的としています。」開発者は AJAX または AJAX に似たリクエストを使用して Web ページを更新するため、http 制限についての議論がますます増えています。
RFC にあるように、Web サーバーへのオープン接続は 2 つしか取得できませんでした。
しかし、ここにコードがあります:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
namespace ConnectionTest
{
public class RequestCounter
{
public int Counter = 0;
public void Increment()
{
Interlocked.Increment(ref Counter);
}
}
public class RequestThread
{
public AutoResetEvent AsyncWaitHandle { get; private set; }
public RequestCounter RequestCounter;
public String Url;
public HttpWebRequest Request;
public HttpWebResponse Response;
public RequestThread(AutoResetEvent r, String u, RequestCounter rc)
{
Url = u;
AsyncWaitHandle = r;
RequestCounter = rc;
}
public void Close()
{
if (Response != null)
Response.Close();
if (Request != null)
Request.Abort();
}
}
public class ConnectionTest
{
static void Main()
{
string url = "http://www.google.com/";
int max = GetMaxConnections(25, url);
Console.WriteLine(String.Format("{0} Max Connections to {1}",max,url));
Console.ReadLine();
}
private static int GetMaxConnections(int maxThreads, string url)
{
RequestCounter requestCounter = new RequestCounter();
List<RequestThread> threadState = new List<RequestThread>();
for (int i = 0; i < maxThreads; i++)
threadState.Add(new RequestThread(new AutoResetEvent(false), url, requestCounter));
List<Thread> threads = new List<Thread>();
foreach (RequestThread state in threadState)
{
Thread t = new Thread(StartRequest);
t.Start(state);
threads.Add(t);
}
WaitHandle[] handles = (from state in threadState select state.AsyncWaitHandle).ToArray();
WaitHandle.WaitAll(handles, 5000); // waits seconds
foreach (Thread t in threads)
t.Abort();
foreach(RequestThread rs in threadState)
rs.Close();
return requestCounter.Counter;
}
public static void StartRequest(object rt)
{
RequestThread state = (RequestThread) rt;
try
{
state.Request = (HttpWebRequest)WebRequest.Create(state.Url);
state.Request.ReadWriteTimeout = 4000; //Waits 4 seconds
state.Response = (HttpWebResponse)state.Request.GetResponse();
if (state.Response.StatusDescription.Equals("OK", StringComparison.InvariantCultureIgnoreCase))
state.RequestCounter.Increment();
//Do not close, or you will free a connection. Close Later
//response.Close();
}
catch (WebException e)
{
//Console.WriteLine("Message:{0}", e.Message);
state.Close();
}
catch (ThreadAbortException e)
{
//Console.WriteLine("Thread Aborted");
state.Close();
}
catch(Exception e)
{
//Console.WriteLine("Real Exception");
state.Close();
}
finally
{
state.AsyncWaitHandle.Set();
}
}
}
}
int counter = 0;
while(true) {
try{
Open New Connection
counter++;
}
catch()
{
Trace.WriteLine(counter);
}
}
制御フローに例外を使用するのが大好きです;)
コメントはできません:)しかし、ドンの答えは堅実なものです。サービスを監視する必要がある期間に応じて、netstat をスケジュールしてファイルにパイプアウトし、期間の終わりにデータを確認することができます。
出力データをクリーンアップして必要なものだけを表示するには、logparser と Excel の組み合わせが必要になる場合があります。
netstat の良い点は、「おしゃべり」を排除して、対象のプロセスに接続されている接続 (pid による) のみを確認できることです。
それ以外の場合は、tcpv4 (または v6) perfmon カウンターを介して、tcp を使用してサーバーへの接続数を監視できます。この接続には、サーバーへのすべての接続が含まれますが、探しているものの大まかなアイデアを得ることができる場合があります。
接続しているサーバーが Windows ボックスであり、WMI を実行している場合、この情報が格納されているレジストリ キーを見つけて、そこに情報を取得することができます。つまり、接続するユーザーが WMI 権限を持っている場合です。
ここにいくつかの PSEUDO コードがあります:
connection = MakeNewConnection("ServerAddress");
while (connection.connected)
{
connectionCounter++;
connection = MakeNewConnection("ServerAddress");
}
最後に、connectionCounter には、作成できる接続の合計が含まれている必要があります。必要に応じて、これに必要な C# コードの種類を実際に確認できます。
PS。サーバーに対して行うのはあまり良いことではなく、おそらく1日以内に禁止されるでしょう:P.