 
        
        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), и на практике используется именно этот подход.
