每台服务器的连接数量? C#,网络

时间:2009-04-18 23:17:56

标签: c# .net httpwebrequest

我正在连接第三方服务器。我知道他们现在允许来自同一个远程用户的8个连接。但是,我不知道他们是否会提高或降低连接限制。所以我希望我的应用程序能够动态找到答案。我怎么能这样做?

我正在使用C#,MSVS 2008

我为能给我C#工作的人开始了赏金。如果没有人那么我会给它最好的答案。

我发现这很难做到并尝试了几次失败:(

8 个答案:

答案 0 :(得分:8)

默认情况下,这不是服务器向客户端提供的信息。要知道的唯一方法是保持打开连接直到它失败(坏主意),或者要求服务器所有者提供可以轮询的服务,该服务返回此信息。

编辑:在仔细考虑了这个问题之后,我不确定是否可以通过“探测”来确定这一点,并且具有任何真实的准确度。如果服务器在达到其连接限制时返回503 Server Busy(我假设在我提出原始建议时会发生),那么测试会更容易。但通常当服务器超过其连接限制时,它们只是在新连接可用之前才会响应。客户端只是等待响应。没有什么难以区分服务器,因为已达到连接限制需要10秒钟才能响应,服务器因任何其他原因需要10秒钟才能响应。

此外,即使您仍尝试以这种方式对其进行测试,您对服务器的请求也需要保持打开足够长的时间,以确保您创建的第一个连接(以及所有当第n个请求超时时,后续的)仍然打开。这意味着要么调用一个需要任意长时间返回的服务 - 一个长时间运行的进程或一个Thread.Sleep();或者下载一个不方便的大文件。这两种方法都是效率极低的。

答案 1 :(得分:2)

穷人做这件事的方法就是炮轰netstat,抓住标准输出并检查它。它为您提供了与其他计算机的当前连接的快照。从中您可以确定您连接到特定服务器的次数。

-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计数器监视服务器的连接数。此连接将包括与服务器的所有连接,但您可能能够大致了解您要查找的内容。