Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 05.11.2014, 16:25
proektant proektant вне форума
Прохожий
 
Регистрация: 05.11.2014
Сообщения: 1
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию Создать модуль быстрого сканера портов ТСР

У меня есть код, но необходимо сделать файл .exe. Необходимо сделать так, чтобы это всё было на Форме
Сам код:

Код:
unit Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, winsock2, ComCtrls;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    Label1: TLabel;
    AddressEdit: TEdit;
    Label2: TLabel;
    StartPortEdit: TEdit;
    EndPortEdit: TEdit;
    Label3: TLabel;
    Button1: TButton;
    DisplayMemo: TRichEdit;
    ProgressBar1: TProgressBar;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    function LookupName: TInAddr;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//Функция преобразвывающся введённый адрес сервера в спецформат
//Если введено символьное имя, то она преобразовывает его сначала в IP адрес,
//а потом переводит в спец формат
function TForm1.LookupName: TInAddr;
var
 HostEnt: PHostEnt;
 InAddr: TInAddr;
begin
 if Pos('.', AddressEdit.Text)>0 then
  InAddr.s_addr := inet_addr(PChar(AddressEdit.Text))
 else
  begin
  HostEnt := gethostbyname(PChar(AddressEdit.Text));
  FillChar(InAddr, SizeOf(InAddr), 0);
  if HostEnt <> nil then
   begin
    with InAddr, HostEnt^ do
     begin
      S_un_b.s_b1 := h_addr^[0];
      S_un_b.s_b2 := h_addr^[1];
      S_un_b.s_b3 := h_addr^[2];
      S_un_b.s_b4 := h_addr^[3];
     end;
   end
  end;
  Result := InAddr;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 i,j,s, opt, index: Integer;
 FSocket: array [0..41] of TSOCKET; //Массив сокетов
 busy   : array [0..41] of boolean; //Массив, в котором будет храниться информация о каждом сканируемом сокете
 port   : array [0..41] of integer; //Массив сканируемых портов
 addr   : TSockAddr;
 hEvent : THandle; //Объект для обработки сетевых событий
 fset   : TFDset;
 tv     : TTimeval;
 tec    :PServEnt;
 PName:String;
 GInitData : TWSADATA;
begin
 // Устанавливаю максимальное и минимальное значение полоски состояния сканирования
 //Я устанавливаю в минимум начальный порт сканирования, а в максимум - конечный порт
 ProgressBar1.Min:=StrToInt(StartPortEdit.Text);
 ProgressBar1.Max:=StrToInt(EndPortEdit.Text);

 //Инициализирую WinSock
 WSAStartup(MAKEWORD(2,0), GInitData);

 //Записываю в переменную i значение начального порта
 i:=StrToInt(StartPortEdit.Text);

 //Заполняю основные поля структуры addr, которая будет использоваться
 //при вызове функции connect
 addr.sin_family := AF_INET;
 addr.sin_addr.s_addr := INADDR_ANY;

 //Вывожу сообщение о том, что начат поиск введённого хоста
 DisplayMemo.SelAttributes.Color:=clTeal;
 DisplayMemo.SelAttributes.Style:=DisplayMemo.SelAttributes.Style+[fsBold];
 DisplayMemo.Lines.Add('Поиск хоста');

 //LookupName - эта функция написана выше и она возвращяет адрес в спец формате указанного сервера
 //Результат этой функции я записываю в поле адреса сервера структуры addr
 addr.sin_addr := LookupName;

 //Вывожу сообщение о том, что начато сканирование
 DisplayMemo.SelAttributes.Color:=clTeal;
 DisplayMemo.SelAttributes.Style:=DisplayMemo.SelAttributes.Style+[fsBold];
 DisplayMemo.Lines.Add('Сканирование...');

 //В index находиться количество сокетов проверяемых за один раз
 index:=40;

 //Создаю объект для обработки сетевых событий
 hEvent := WSACreateEvent();
 while i<StrToInt(EndPortEdit.Text) do
  begin
   ///Всем элементам массива busy присваиваю значение false
   for j:=0 to index do
    busy[j]:=false;

   //В этом цикле будут асинхронно посылаться запросы на моединение
   //переменная j будет изменяться от 0 до максимального количества
   //элементов в массиве
   for j:=0 to index do
    begin
     //Если j-й порт превысил значение указанного максимального
     //порта, то прервать цикл
     if i>StrToInt(EndPortEdit.Text) then
      begin
       index:=j-1;
       break;
      end;

     //Инициализирую очередной j-й сокет из массива FSocket
     FSocket[j] := socket(AF_INET, SOCK_STREAM, IPPROTO_IP);

     //Добавляю j-й сокет к объекту событий с помощью WSAEventSelect
     //1-й параметр - Добавляемый сокет
     //2-й параметр - объект событий, который был создан с помощью WSACreateEvent
     //3-й параметр - какие события ожидать. Тут я указываю FD_WRITE - события записи и FD_CONNECT - события о заключении соединения
     WSAEventSelect(FSocket[j], hEvent, FD_WRITE + FD_CONNECT);

     //Указываем порт, на который надо произвести попытку соединения
     addr.sin_port := htons(i);

     //Попытка коннекта на очередной порт
     connect(FSocket[j], @addr, sizeof(addr));

     //Даём ОС поработать и обработать накопившиеся события.
     //Если этого не делать, то вовремя сканирования будет
     //происходить эффект зависания
     Application.ProcessMessages;

     //Проверяю, были ли ошибки.
     if WSAGetLastError()=WSAEINPROGRESS then
      begin
       //Если ошибка произошла, то закрываю этот порт
       closesocket (FSocket[j]);
       //Устанавливаю соответствующий элемент в массиве busy в true
       //чтобы потом не проверять этот порт, потому что он всё равно
       //уже закрыт
       busy[j]:=true;
      end;

     //Указываю в массиве port, на какой именно порт мы сейчас послали запрос
     port[j]:=i;

     //Увеличиваю счётчик i в котором я отслеживаю, какой порт сейчас сканируеться
     //чтобы на следующем этапе цикла for запустить сканирование следующего порта
     i:=i+1;
    end;

   //Обнуляю переменную fset
   FD_Zero(fset);

   //Заполняю сканируемый массив сокетов в переменную fset
   for j := 0 to index do
    begin
     if busy[j] <> true then
      FD_SET (FSocket[j], fset);
    end;

   //Даём ОС поработать и обработать накопившиеся события.
   Application.ProcessMessages;

   //Заполняю структуру, в которой указано время ожидания события от сокета
   tv.tv_sec := 1; //Мы будем ждать 1 секунду
   tv.tv_usec := 0;

   //Ожидаем пока произойдёт хотя бы одно событие от любого из сокетов
   s:=select (1, nil, @fset, nil, @tv);

   //Даём ОС поработать и обработать накопившиеся события.
   Application.ProcessMessages;

   //Запускаю массив, в котором будет проверятся, какие из сокетов в массиве FSocket
   //прошли коннект успешно, а какие нет.
   for j := 0 to index do
    begin
     //Проверяем, был ли закрыт соответствующий порт из-за ошибки
     //Если да, то нет смысла его проверять
     if busy[j] then continue;

     if FD_ISSET (FSocket[j], fset) then
      begin
       //В переменную s записываеться размер перменной Opt
       s:=Sizeof(Opt);
       opt:=1;
       //Получаю состояние текущего j-го сокета
       //результат состояния будет в переменной opt
       getsockopt(FSocket[j], SOL_SOCKET, SO_ERROR, @opt, s);

       //Если opt равно 0 то порт открыт и к нему можно подключится
       if opt=0 then
         begin
          //Пытаюсь узнать символьное имя порта
          tec := getservbyport(htons(Port[j]),'TCP');
          if tec=nil then
           PName:='Unknown'
          else
           begin
            PName:=tec.s_name;
           end;
          //Вывожу сообщение об открытом порте
          DisplayMemo.Lines.Add('Хост:'+AddressEdit.Text+': порт :'+IntToStr(Port[j])+' ('+Pname+') '+' открыт ');
         end;
      end;
     //Закрыть j-й сокет, потому что он больше уже не нужен
     closesocket(FSocket[j]);
    end;
   //Увеличивею позицию в ProgressBar1
   ProgressBar1.Position:=i;
  end;
 //Закрываю объект событий
 WSACloseEvent(hEvent);

 //Вывожу сообщение о конце сканирования
DisplayMemo.SelAttributes.Color:=clTeal;
 DisplayMemo.SelAttributes.Style:=DisplayMemo.SelAttributes.Style+[fsBold];
 DisplayMemo.Lines.Add('Сканирование закончено...');
 ProgressBar1.Position:=0;
end;

end.
Админ: Пользуемся тегами для оформления кода! При рецедиве последует бан.


P.S. Это снова картинка с лабы (авторы хотели сразу указать студентам, что должно получиться в итоге)
Изображения
Тип файла: jpg Задание 5.jpg (31.5 Кбайт, 7 просмотров)

Последний раз редактировалось Admin, 05.11.2014 в 19:42.
Ответить с цитированием
 


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 22:41.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025