.net中的线程池肯定用了什么优化技术,和直接用线程差别巨大

由于现在很难用syn扫描,于是那天另做一个标准tcp扫描的时候发现了一个问题。

本来想象中很简单,就是一个多线程,一个tcpclinet而已。

扫描部分代码如下。多说一句,由于.net下无论tcpclient还是socket都没有connect timeout(连接超时)的设置,网上借鉴了一下别人的用AutoResetEvent的等待做超时,异步连接,如果超时之前连接成功就set(),如果等到100毫秒还没异步连接成功就认为失败。

        private void ec(IAsyncResult iar)
        {
            try
            {
                TcpClient tc = (TcpClient)iar.AsyncState;
                tc.EndConnect(iar);
                are.Set();
            }
            catch { }
        }
        AutoResetEvent are = new AutoResetEvent(false);
        private void ceshi(IPEndPoint ipp)
        {
            TcpClient tc = new TcpClient();
            tc.BeginConnect(ipp.Address, ipp.Port, ec, tc);
            are.WaitOne(100);
            if (tc.Connected)
            {
                Console.WriteLine(ipp.ToString());
            }
            try
            {
                tc.Close();
            }
            catch { }
        }

就这样一个同样的代码,我直接用Thread开512个线程去执行ceshi这个方法结果,几秒钟cpu100%了卡住了。我用vs2010性能分析工具,说全都是由于BeginConnect EndConnect和Close几个方法占用的cpu。

但是奇怪的是,同样还是上面的代码,用ThreadPool去执行ceshi,同样用512的线程的话,cpu占用率就基本为0,不要怀疑线程池的限制了线程数,我ThreadPool.SetMaxThreads(int.MaxValue, int.MaxValue);了

 

而且从netstat -ano看,确实是大量的连接,确实是512个线程连接,从路由器中看也是如此。

 

难道线程池还能优化TcpClient?真是百思不得其解啊。

 

顺便说一下,如果直接用Thread 512个线程的话,从任务管理器中看,上来就会有512个线程(其实还有一些辅助线程上来600多),而用线程池的话,他会从几十个线程开始2个2个的往上加,最后也达到600多个,稳定到600多线程,保证512个线程去连接是没有问题的。

 

所以上来说一下,做这种大量网络操作的同志们还是用线程池吧。

你可能感兴趣的:(thread,多线程,.net,优化,socket,路由器)