我正在连接第三方服务器。我知道他们现在允许来自同一个远程用户的8个连接。但是,我不知道他们是否会提高或降低连接限制。所以我希望我的应用程序能够动态找到答案。我怎么能这样做?
我为能给我C#工作的人开始了赏金。如果没有人那么我会给它最好的答案。
我发现这很难做到并尝试了几次失败:(
答案 0 :(得分:8)
默认情况下,这不是服务器向客户端提供的信息。要知道的唯一方法是保持打开连接直到它失败(坏主意),或者要求服务器所有者提供可以轮询的服务,该服务返回此信息。
编辑:在仔细考虑了这个问题之后,我不确定是否可以通过“探测”来确定这一点,并且具有任何真实的准确度。如果服务器在达到其连接限制时返回503 Server Busy
(我假设在我提出原始建议时会发生),那么测试会更容易。但通常当服务器超过其连接限制时,它们只是在新连接可用之前才会响应。客户端只是等待响应。没有什么难以区分服务器,因为已达到连接限制需要10秒钟才能响应,服务器因任何其他原因需要10秒钟才能响应。
此外,即使您仍尝试以这种方式对其进行测试,您对服务器的请求也需要保持打开足够长的时间,以确保您创建的第一个连接(以及所有当第n个请求超时时,后续的)仍然打开。这意味着要么调用一个需要任意长时间返回的服务 - 一个长时间运行的进程或一个Thread.Sleep();或者下载一个不方便的大文件。这两种方法都是效率极低的。
答案 1 :(得分:2)
-don
答案 2 :(得分:1)
在你的情况下,更好的想法可能不是真正关心。我会尝试逐个打开连接并检查应用程序的性能。只要通过打开另一个连接增加性能,继续打开新连接。当性能停止增加时,您可以合理地接近最佳连接数。
答案 3 :(得分:1)
我会把这个赏金好先生。不完全确定你为什么要这样做以及为什么有人允许8个连接。
1999年定义(RFC 2616)“客户 应该使用持久连接 限制同时的数量 他们维持的联系 给定服务器。单用户客户端 不应该保持2个以上 与任何服务器或代理的连接。 代理应该最多使用2 * N. 连接到另一台服务器或 代理,其中N是数字 同时活跃的用户。这些 准则旨在改进 HTTP响应时间并避免 拥堵。“自开发商以来 使用AJAX或类似AJAX的请求 更新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();
}
}
}
}
答案 4 :(得分:0)
这里有一些PSEUDO代码:
connection = MakeNewConnection("ServerAddress");
while (connection.connected)
{
connectionCounter++;
connection = MakeNewConnection("ServerAddress");
}
最后,您的connectionCounter应该包含您可以进行的总连接。如果您愿意,我实际上可以看到这需要哪种C#代码。
PS。这对服务器来说不是一件好事,它可能会让你在一天之内被禁止:P。
答案 5 :(得分:0)
如果您连接的服务器是Windows框并且正在运行WMI,那么您可以找出存储此信息的注册表项并获取其中的信息。也就是说,如果您连接的用户具有WMI权限。
答案 6 :(得分:0)
int counter = 0;
while(true) {
try{
Open New Connection
counter++;
}
catch()
{
Trace.WriteLine(counter);
}
}
喜欢使用控制流的例外;)
答案 7 :(得分:0)
我无法发表评论:)但Don's答案是可靠的。根据您需要监控服务的时间长短,您可以安排netstat管道输出到文件,并在时间段结束时查看数据。
清理输出数据以查看您想要的内容可能采用logparser和excel的组合。
关于netstat的好处是你可以消除'chatter',只看到与感兴趣的过程相关的连接(通过pid)。
否则,您可以使用tcp通过tcpv4(或v6)perfmon计数器监视服务器的连接数。此连接将包括与服务器的所有连接,但您可能能够大致了解您要查找的内容。