
3. Методические указания.
Создадим свой сканер портов.
Запустите Delphi. Перенесите на форму следующие компоненты:
два компонента TButton (с именами Button1 и Button2);
два компонента TLabel (с именами Labell и Label2);
два компонента TEdit (с именами Edit1 и Edit2);
компонент TMemo (имя Memo1).
Теперь у формы поменяйте свойство Caption на «Сканер портов», у кнопки Button1 поменяйте свойство caption на Сканировать, у кнопки Button2 поменяйте свойство Caption на Выход, у Labell на Начальный порт, а у Label2 на Конечный порт. В компоненте Memo1 удалите из свойства Lines все значения, а свойству ScrollBars установите значение ssVertical. У компонентов Edit1 и Edit2 присвойте свойству Text значения соответственно 1 и 2.
Если вы все сделали правильно, то у вас должно получиться нечто похожее на изображенное на рис. 2. После нажатия кнопки мы будем сканировать порты, начиная от номера, указанного в Editl, до номера, указанного в Edit2.
Рисунок 2 Форма приложения.
Теперь нужно перенести на форму самый важный компонент - TcpClient с закладки Internet. В нем фирма Borland уже реализовала все необходимые функции для работы с сетью по протоколу TCP/IP, в том числе и сканирование.
Код процедуры сканирования достаточно легкий и занимает несколько строчек. Но для начала создадим событие OnClick кнопки «Выход». Для этого необходимо дважды щелкнуть мышью на ней и в открывшемся окне редактора написать Self.Close.
После этого необходимо создать событие OnClick кнопки «Сканировать». В этом обработчике напишите следующее (рис. 3).
Рисунок 3 Код процедуры сканирования
Комментарии к коду.
В коде использована функция InputQuery. Она выводит стандартное окно ввода. Функции передается три параметра:
текст заголовка окна;
текст, отображаемый над строкой ввода;
переменная типа строки, куда будет записан результат.
Если пользователь ввел значение и нажал кнопку OK, то функция вернет true, иначе возвратит false. Поэтому использована конструкция:
if not InputCuery (...) then exit;
Она означает: "Если пользователь не нажат OK, то выйти". После этого запускается цикл, внутри которого будут перебираться все порты:
for i:=StrToInt(Editl.Text) to StrTolnt(Edit2.Text) do
Сама процедура сканирования находится между begin и end цикла. Первая строка указывает на то, какой порт мы хотим открыть:
TcpClient1.RemotePort:=IntToStr(i);
Здесь мы заполняем у компонента TcpClientl свойство RemotePort значением, указанным в переменной i. Свойство RemotePort является строковым, поэтому число i нужно конвертировать в строку с помощью inttostr. Переменная i у нас указывает порт, который надо сканировать.
Следующей строкой пытаемся открыть порт с помощью метода Open компонента TcpClient1:
TcpClientl.Open;
Если свойство Connected компонента TсpСlient1 равно true, то соединение прошло успешно, в противном случае порт закрыт. Последнее, что происходит— порт закрывается с помощью вызова метода close. Если мы открыли порт, но не закрыли, то при следующей попытке открыть произойдет ошибка.
Примечание. Созданный сканер — вполне рабочая программа. Но в Windows сканирование 1 000 портов приведенным способом проходит очень долго, поэтому лучше сканировать маленькими порциями — не более 10 портов. Значительно ускорить процесс сканирования портов позволяет использование сокетов (sockets), и на практике используется именно этот подход.