“无法连接到远程服务器失败”中的HttpWebRequest(“Unable to connect

2019-08-22 16:55发布

我使用VSTS 2008 + C#+。NET 3.5的开发控制台应用程序,我请求发送到另一台服务器(Windows Server 2008上的IIS 7.0)。 我发现,当请求线程#是大(例如2000线),客户端会收到错误“无法连接到远程服务器失败”响应调用时=(HttpWebResponse)request.GetResponse()我的困惑是 - 我有超时设置为较大的值,但我得到了一分钟之内这样的失败消息。 我想,即使连接确实比IIS可以起到较大,客户不应该得到这样的这么快就失败消息,超时后应该得到这样的消息。 任何意见? 任何想法有什么不好? 任何想法,使通过IIS 7.0投放较多数量的并发连接?

这里是我的代码,

   class Program
    {
        private static int ClientCount = 2000;
        private static string TargetURL = "http://labtest/abc.wmv";
        private static int Timeout = 3600;

        static void PerformanceWorker()
        {
            Stream dataStream = null;
            HttpWebRequest request = null;
            HttpWebResponse response = null;
            StreamReader reader = null;
            try
            {
                request = (HttpWebRequest)WebRequest.Create(TargetURL);
                request.Timeout = Timeout * 1000;
                request.Proxy = null;
                response = (HttpWebResponse)request.GetResponse();
                dataStream = response.GetResponseStream();
                reader = new StreamReader(dataStream);

                // 1 M at one time
                char[] c = new char[1000 * 10];

                while (reader.Read(c, 0, c.Length) > 0)
                {
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message + "\n" + ex.StackTrace);
            }
            finally
            {
                if (null != reader)
                {
                    reader.Close();
                }
                if (null != dataStream)
                {
                    dataStream.Close();
                }
                if (null != response)
                {
                    response.Close();
                }
            }
        }

        static void Main(string[] args)
        {
            Thread[] workers = new Thread[ClientCount];
            for (int i = 0; i < ClientCount; i++)
            {
                workers[i] = new Thread((new ThreadStart(PerformanceWorker)));
            }

            for (int i = 0; i < ClientCount; i++)
            {
                workers[i].Start();
            }

            for (int i = 0; i < ClientCount; i++)
            {
                workers[i].Join();
            }           

            return;
        }
    }

Answer 1:

千电子伏回答你已经问,我只想补充一点,创造这么多线程是不是真的很好的设计解决方案(只是一个上下文切换的开销是很大的负),再加上它不能扩展好。

简单的回答是:使用异步操作来阅读,而不是创造一堆线程的数据。 或至少使用线程池(和更低的工作线程数)。 请记住,一个消息来源更多的连接只能加快速度,直到某种程度。 尝试基准它,你会看到,大概3-5个连接的运行速度更快,在2000年,你现在正在使用。

你可以阅读更多有关异步客户机/服务器体系结构(IOCP - 输入/输出完成端口)和它的优点在这里。 你可以从这里开始:

MSDN -使用异步服务器套接字

MSDN -异步服务器套接字示例

CodeProject上-多线程.NET TCP服务器实例

所有这些例子使用较低水平TCP对象,但它可以应用到的WebRequest / WebResponse的为好。

UPDATE

要尝试线程池的版本,你可以这样做:

ManualResetEvent[] events = new ManualResetEvent[ClientCount];
for (uint cnt  = 0; cnt < events.Length; cnt++)
{
  events[cnt] = new ManualResetEvent(false);
  ThreadPool.QueueUserWorkItem(obj => PerformanceWorker());
}

WaitHandle.WaitAll(events);

没有测试,可能需要一些调整。



Answer 2:

我想你已经刷爆了该网站的应用程序池队列。 默认值是1000个请求,你充斥服务器2000点的要求一次全部更多或更少。 增加超时不会解决这个问题。

尝试增加队列长度为站点驻留在应用程序池。

你应该尝试捕捉潜在的HTTP状态,这会给你一个线索,什么是怎么回事。

更新:

当我运行你的代码,并尝试下载一个相当大的文件(200MB)我得到(503) Server Unavailable. 。 增加了应用程序池的请求队列的大小来解决这个(我设置矿10000)。

只有一次,我才看到Unable to connect to remote server和可悲的是已经无法复制。 此错误听起来像有东西在TCP / IP层破裂。 您可以发布完整的例外呢?



Answer 3:

转到智能线程池和downlod代码。 这是一个实例线程池限制的线程数。 在.NET线程池可以在连接到网络服务器和SQL服务器的应用程序有问题。

改变回路本

static void Main(string[] args)
        {
            var stp = new SmartThreadPool((int) TimeSpan.FromMinutes(5).TotalMilliseconds,
                                          Environment.ProcessorCount - 1, Environment.ProcessorCount - 1);
            stp.Start();
            for (var i = 0; i < ClientCount; i++)
            {
                stp.QueueWorkItem(PerformanceWorker);
            }
            stp.WaitForIdle();
            stp.Shutdown();

            return;
        }

这限制了线程池来使用PROC每1个线程。 直到演出开始降低,调整这件事。 太多线程比太少差。 你很多发现,这是最佳的。

另外这个配置添加到您。 100的值是一个默认的我用。 有一种方法在代码中这样做,但该语法现在脱离了我。

<system.net>

    <connectionManagement>

        <add address=“*“ maxconnection=“100“ />

    </connectionManagement>

</system.net>


Answer 4:

我使用Visual Studio 2005中如何发送短信,这里是我的代码:

IPHostEntry host;
host = Dns.GetHostEntry(Dns.GetHostName());
UriBuilder urlbuilder = new UriBuilder();
urlbuilder.Host = host.HostName;
urlbuilder.Port = 4719;
string PhoneNumber = "9655336272";
string message = "Just a simple text";
string subject = "MMS subject";
string YourChoiceofName = "victoria";
urlbuilder.Query = string.Format("PhoneNumber=%2B" + PhoneNumber + "&MMSFrom=" + YourChoiceofName + "&MMSSubject=" + subject + "&MMSText=" + message);//+ "&MMSFile=http://127.0.0.1/" + fileName
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(new Uri(urlbuilder.ToString(), false));
HttpWebResponse httpResponse = (HttpWebResponse)(httpReq.GetResponse());


文章来源: “Unable to connect to remote server fail” in HttpWebRequest