Потоки — это очень мощная и удобная вещь, позволяющая создать многозадачность даже внутри отдельного приложения. Но у них есть один большой недостаток — программисты, познакомившись с потоками, начинают использовать их везде, где это надо и не надо.
Я видел много сканеров, которые используют по 20—50 потоков для одновременного сканирования большого количества портов. Я понимаю, что пример, который мы рассмотрели в главе 4, был очень медленным, и его надо ускорять, но не таким же методом. Попробуйте на досуге реализовать сканирование с помощью потоков. Вы увидите, что это не так уж и просто. Ну и, конечно же, вы уже знаете, что потоки излишне нагружают систему.
Сейчас вам предстоит увидеть, как можно реализовать быстрое сканирование портов без использования потоков. А тогда как? Конечно, с помощью асинхронной работы с сетью. Можно создать несколько асинхронных сокетов и запустить ожидание соединения. Потом собрать все сокеты в набор fd_set и выполнить функцию select в ожидании события соединения с сервером. По завершении ее выполнения необходимо проверить все сокеты на удачное соединение и вывести результат.
Давайте попробуем реализовать это на примере. Для иллюстрации сказанного создайте новое приложение MFC Application на основе диалогового окна. При этом не включайте опцию поддержки WinSock в разделе Advanced Features. В данном случае мы будем использовать некоторые функции WinSock2. Поэтому подключите заголовочный файл winsock2.h вручную и укажите в свойствах проекта необходимость использования библиотеки ws2_32.lib. Все это мы уже не раз делали, и это не должно вызвать затруднений.
Теперь откройте в редакторе ресурсов главное окно программы. Оформите его в соответствии с рис. 6.1. Здесь необходимо добавить три поля ввода Edit Box, список List Box и кнопку, по нажатии которой будет происходить сканирование. Для всех полей ввода нужно создать следующие переменные: