views:

77

answers:

3

I am trying to run a small app that scans ports and checks to see if they are open using and practicing with threadpools. The console window will ask a number and scans ports from 1 to X and will display each port whether they are open or closed. My problem is that as it goes through each port, it sometimes stops prematurely. It doesn't stop at just one number either, its pretty random. For example it I specify 200. The console will scroll through each port then stops at 110. Next time I run it, it stops at 80.

Code Left out some of the things, assume all variables are declared where they should. First part is in Main.

static void Main(string[] args)
    {
        string portNum;
        int convertedNum;
        Console.WriteLine("Scanning ports 1-X");
        portNum = Console.ReadLine();
        convertedNum = Convert.ToInt32(portNum);
        try
        {
            for (int i = 1; i <= convertedNum; i++)
            {
                ThreadPool.QueueUserWorkItem(scanPort, i);
                Thread.Sleep(100);

            }
        }
        catch (Exception e)
        {
           Console.WriteLine("exception " + e);
        }
    }

    static void scanPort(object o)
    {
        TcpClient scanner = new TcpClient();
        try
        {
            scanner.Connect("127.0.0.1",(int)o);
            Console.WriteLine("Port {0} open", o);
        }
        catch
        {
            Console.WriteLine("Port {0} closed",o);
        }
    }

}
+3  A: 

If this is the entire code, then the error is probably caused by you just falling through to the end of main() without waiting for all your thread pool threads to finish. The ThreadPool threads are all aborted once your main thread exits after falling through main(). Try removing the Thread.Sleep(100) (it is not needed, this is the wrong way, you'd never know for how long to sleep for and it partially defeats the purpose of using a ThreadPool in the first place) and you will probably not even check a single port!

Instead you could have each of your worker threads set an event and use WaitAll in main for all events to finish. See http://msdn.microsoft.com/en-us/library/3dasc8as.aspx for an example.

Edit: Thinking this through, the solution referenced at the link above is probably less than ideal for you as well (it might involve having to allocate an array of 65000 events, this would be excessive). In .net 4 you could use a CountdownEvent like this:

Sorry, I gotta run, but check this example http://msdn.microsoft.com/en-us/library/system.threading.countdownevent.aspx and let us know when you have further questions, I'm sure someone can and will elaborate or suggest a better solution and a solution more suitable for .net3

Ben Schwehn
It looks to me like Ben hit the nail on the head. If you are doing this to learn more about threading, you might want to consider explicitally setting the max threads in the pool using SetMaxThreads(). MSDN says that the default is 250 threads in the pool. For some types of operations you might get better performance with a larger or smaller number of concurrent threads.
Al Crowley
A: 

What OS? Don't forget, different versions of XP have tcp connection limits, while you may also be triggering anti DDOS protection as well.

Also, your logic is flawed. Just because TcpClient.Connect excepted, doesn't mean the port is closed. You should be capturing and displaying that exception's details as I imagine it will offer you greater insight into why your code is stopping. Keep in mind, its possible to throw a SocketException or SecurityException as well.

Serapth
A: 

Concerning the threading part, you could consider using the Task Parallel Library (TPL) instead of directly accessing the ThreadPool. IMHO it offers a more simple use and a more intuitive/readable syntax.

Simpzon