Создать модуль быстрого  сканера портов ТСР
			 
			 
			
		
		
		
		У меня есть код, но необходимо сделать файл .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. Это снова картинка с лабы (авторы хотели сразу указать студентам, что должно получиться в итоге)  
		
	
		
		
			
		
		
		
		
		
		
		
						  
				
				Последний раз редактировалось Admin, 05.11.2014 в 19:42.
				
				
			
		
		
	
		
		
	
	
	 |