Форум по 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.
Ответить с цитированием
  #2  
Старый 06.11.2014, 08:37
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

А в чём хоть проблема-то? Это и так уже готовый юнит формы. Всего лишь что нужно сделать, так это открыть новый проект, накидать на форму компонентов прям по списку секции type (Panel1, Label1 etc.) заменить стандартный код на вышеприведенный и подключить к кнопке Button1 процедуру клика
Ответить с цитированием
Ответ


Delphi Sources

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

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

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

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


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


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

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

ВКонтакте   Facebook   Twitter