Сканирование портов с использованием пула потоков - PullRequest
1 голос
/ 11 июня 2010

Я пытаюсь запустить небольшое приложение, которое сканирует порты и проверяет, открыты ли они при использовании и использовании потоковых пулов.В окне консоли будет задан номер, и будут сканироваться порты от 1 до X, и будет отображаться каждый порт независимо от того, открыты они или нет.Моя проблема в том, что когда он проходит через каждый порт, он иногда останавливается преждевременно.Это не останавливается только на одном числе, это довольно случайно.Например, я указываю 200. Консоль прокручивает каждый порт, затем останавливается на 110. В следующий раз, когда я запускаю его, он останавливается на 80.им следует.Первая часть в 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 ]

3 голосов
/ 11 июня 2010

Если это весь код, то ошибка, вероятно, вызвана тем, что вы просто провалились до конца main(), не дожидаясь завершения всех потоков вашего пула потоков. Все потоки ThreadPool прерываются после выхода из основного потока после провала через main(). Попробуйте удалить Thread.Sleep(100) (это не нужно, это неправильный способ, вы никогда не узнаете, как долго вы будете спать, и это частично откажется от цели использования ThreadPool в первую очередь), и вы, вероятно, даже не проверить ни одного порта!

Вместо этого вы можете настроить каждый из рабочих потоков на событие и использовать WaitAll в main для завершения всех событий. См. http://msdn.microsoft.com/en-us/library/3dasc8as.aspx для примера.

Изменить: Подумав об этом, решение, на которое ссылается ссылка выше, вероятно, также не идеально подходит для вас (это может потребовать выделения массива из 65000 событий, это было бы чрезмерно). В .net 4 вы можете использовать CountdownEvent так:

Извините, я должен бежать, но посмотрите этот пример http://msdn.microsoft.com/en-us/library/system.threading.countdownevent.aspx и сообщите нам, когда у вас возникнут дополнительные вопросы, я уверен, что кто-то может и будет разрабатывать или предлагать лучшее решение и решение, более подходящее для этого. net3

0 голосов
/ 12 июня 2010

Что касается потоковой части, вы можете рассмотреть возможность использования Task Parallel Library (TPL) вместо прямого доступа к ThreadPool. ИМХО, он предлагает более простое использование и более понятный / читаемый синтаксис.

0 голосов
/ 11 июня 2010

Какая ОС?Не забывайте, что разные версии XP имеют ограничения по tcp-соединению, хотя вы также можете запускать защиту от DDOS.

Кроме того, ваша логика несовершенна.То, что TcpClient.Connect исключен, не означает, что порт закрыт.Вы должны фиксировать и отображать детали этого исключения, так как я полагаю, что это поможет вам лучше понять, почему код останавливается.Имейте в виду, что также можно генерировать исключение SocketException или SecurityException.

...