Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как в Delphi опросить сеть на IP адреса.  (Прочитано 22102 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Bosh
Гость
« : 18-11-2003 11:55 » 

Как в Delphi опросить сеть на IP адреса.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 18-11-2003 12:11 » 

Т.е. узнать какие активны?
Общий принцип: возьми из настроек сети свой IP и маску и пройдись пингом по всем, кроме первого и последнего адреса в сети.
Есть вероятность что и активная машина не откликнется - например если настроена не отвечать.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
DimOC
Гость
« Ответ #2 : 24-11-2003 04:14 » 

в общем, вроде так.
Где-то в цикле формируй IP-адреса (например от 192.165.32.1 до 192.165.32.254) и стартуй функцию с этой строкой в качестве параметра.
У меня там OutSrt переменная (для програмных нужд), если она не нужна, то удали ее.
Этот код работает (тест Windows95/98/Me), но нет потоков, может подвисать 1-2 секунды, в общем кривоват, так что далее улучшай сам.

Код:
function PingHost(HostName: String): String;
 var
   hIP : THandle;
   pingBuffer : array [0..31] of Char;
   pIpe : ^icmp_echo_reply;
   pHostEn : PHostEnt;
   wVersionRequested : WORD;
   lwsaData : WSAData;
   error : DWORD;
   destAddress : In_Addr;
   OutStr: string;

 begin
   // Создаем handle
   hIP := IcmpCreateFile();
   GetMem(pIpe,sizeof(icmp_echo_reply)+sizeof(pingBuffer));
   pIpe.Data := @pingBuffer;
   pIpe.DataSize := sizeof(pingBuffer);
   wVersionRequested := MakeWord(1,1);
   OutStr := '';

   error := WSAStartup(wVersionRequested,lwsaData);
   if (error <> 0)
   then begin
          OutStr := OutStr + 'Нет сетевых сервисов (Error code: '+IntToStr(error)+')';
          if TypeWork = 1
          then Result := OutStr;
          IcmpCloseHandle(hIP);
          WSACleanup();
          FreeMem(pIpe);
          exit;
        end;

   OutStr := 'Pinging '+HostName+'                    ';
   OutStr := CatString(OutStr, 1, 22);
   pHostEn := gethostbyname(PChar(HostName));

   error := GetLastError();
   if (error <> 0) // Ошибка
   then begin
          OutStr := OutStr + ' -> ошибка получения IP-адреса';
          if TypeWork = 1
          then Result := OutStr;
          IcmpCloseHandle(hIP);
          WSACleanup();
          FreeMem(pIpe);
          exit;
        end;

   destAddress := PInAddr(pHostEn^.h_addr_list^)^;

   // Посылаем ping-пакет
   IcmpSendEcho(hIP, destAddress.S_addr, @pingBuffer, sizeof(pingBuffer), Nil, pIpe,
                sizeof(icmp_echo_reply) + sizeof(pingBuffer), 500);

   error := GetLastError();
   if (error <> 0) // Ошибка
   then begin
          OutStr := OutStr + ' -> ping false';
          if TypeWork = 1
          then Result := OutStr;
          IcmpCloseHandle(hIP);
          WSACleanup();
          FreeMem(pIpe);
          exit;
        end;

   // Смотрим некоторые из вернувшихся данных
   OutStr := OutStr + ' -> reply from '+
             IntToStr(LoByte(LoWord(pIpe^.Address)))+'.'+
             IntToStr(HiByte(LoWord(pIpe^.Address)))+'.'+
             IntToStr(LoByte(HiWord(pIpe^.Address)))+'.'+
             IntToStr(HiByte(HiWord(pIpe^.Address)))+
             ' (reply time: '+IntToStr(pIpe.RTTime)+' ms)';

   Result := IntToStr(LoByte(LoWord(pIpe^.Address)))+'.'+
             IntToStr(HiByte(LoWord(pIpe^.Address)))+'.'+
             IntToStr(LoByte(HiWord(pIpe^.Address)))+'.'+
             IntToStr(HiByte(HiWord(pIpe^.Address)));

   if TypeWork = 1
   then Result := OutStr;
   IcmpCloseHandle(hIP);
   WSACleanup();
   FreeMem(pIpe);
 end;
« Последнее редактирование: 21-11-2007 16:17 от Алексей1153++ » Записан
sss
Специалист

ru
Offline Offline

« Ответ #3 : 01-12-2003 08:09 » 

var
    s: socket;
    FInterfaces: INTERFACE_INFO[MAX_INTERFACE_LIST];

begin
....  
n = WSAIoctl(s, SIO_GET_INTERFACE_LIST, 0, 0, FInterfaces,  sizeof(FInterfaces), uBytes, NULL, NULL);
for i = 0 to n - 1 do
 begin
   WSAAddressToString(..., FProtocols[idx], str, &size);
 end;
Записан

while (8==8)
Allex63
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 28-12-2004 13:44 » 

Где-то что-то верно, добавляю идею, что можно не в цикле, а во временно созданных N (например, 256-1) потоках (Threads). Получается быстрее (2-4 сек вместо много-много)
Записан

Мысли должны быть короткие и плоские.
Так их в ROM больше помещается.
x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #5 : 29-12-2004 22:33 » 

Allex, как ты себе представляешь работу машины с 255 одновременно установленными handshake'ами?
« Последнее редактирование: 21-11-2007 16:18 от Алексей1153++ » Записан

x77
Модератор

ro
Offline Offline
Пол: Мужской
меняю стакан шмали на обратный билет с Марса.


« Ответ #6 : 29-12-2004 22:36 » 

открой на компе 255 окон интернет эксплорера и начни их грузить одновременно. грубо, конечно, но примерно так. кроме того, никто не сказал, что в сети доступна только текущая маска. сеть может состоять из нескольких рабочих групп / доменов, где маски будут разными. для 10 рабочих групп ты получишь 2550 возможных адресов, в твоём варианте это эквивалентно 2550 процессов.
Записан

Allex63
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 02-01-2005 06:27 » 

Какие же вы все серьезные! Впрочем, по порядку.
1. Кто заставляет держать HandShake после получения данных о том, что в сети есть такой адрес?
2. Browser's, в особенности IE тормозит в основном по "отъеденной памяти"
3. Число 255 не обязательно означет сканировниние подсетки x.x.x.* Оно может означать и сканирование очередного фрагмента сети с адресами
   xxx.xxx.xxx.xxx -  xxx.xxx.xxx.xxx + 255, например.
4. Есть разница, вполне ощутимая, в подключении (трафик, например)  http и Echo Request/Reply
5. И (козырной валет) на ОЧЕНЬ медленной сетке данный метод возвращал список одной подсети (например, 192.168.2.*) за 3 секунды, и ничего ни с "локирующим" компом не происходило, он оставался жив и вполне весел. Попробуйте!

« Последнее редактирование: 20-12-2007 18:30 от Алексей1153++ » Записан

Мысли должны быть короткие и плоские.
Так их в ROM больше помещается.
Skyhawk
Гость
« Ответ #8 : 02-04-2005 13:37 » 

Но ведь если сеть локальная, зачем пинговать весь диапазон адресов? Не проще получить спиок компьютеров и спросить у каждого его IP адрес - операция в один цикл.
Записан
Allex63
Участник

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 04-04-2005 09:05 » 

Skyhawk wrotes:
Но ведь если сеть локальная, зачем пинговать весь диапазон адресов? Не проще получить спиок компьютеров и спросить у каждого его IP адрес - операция в один цикл.

RXL wrotes:
Есть вероятность что и активная машина не откликнется - например если настроена не отвечать.

Allex:
Вероятность, что настройка/настроение машины не отвечать при получении списка компьютеров выше, чем при прямом Ping. Например, у меня  (у соседа по комнате и еще у кучки народа) ящик весьма "необщительный" и в списке просто не проявляется. А Ping приходится наружу отдавать...
Записан

Мысли должны быть короткие и плоские.
Так их в ROM больше помещается.
Nilbog
Гость
« Ответ #10 : 18-08-2005 09:00 » new

вот кусок   проги на опредиление хоста и ip
 


Код:
function IPAddrToName(IPAddr : string): string;
var
  SockAddrIn: TSockAddrIn;
  HostEnt: PHostEnt;
  WSAData: TWSAData;
begin
  WSAStartup($101, WSAData);
  SockAddrIn.sin_addr.s_addr:= inet_addr(PChar(IPAddr));
  HostEnt:= gethostbyaddr(@SockAddrIn.sin_addr.S_addr, 4, AF_INET);
  if HostEnt <> nil then
    result := StrPas(Hostent^.h_name)
  else
    result:='no';
end;

function GetLocalIPFromHost(var HostName, IPaddr, WSAErr: string): Boolean;
type
  Name = array[0..100] of Char;
  PName = ^Name;
var
  HEnt: pHostEnt;
  HName: PName;
  WSAData: TWSAData;
  i: Integer;
begin
  Result := False;     
  if WSAStartup($0101, WSAData) <> 0 then begin
    WSAErr := 'Winsock is not responding."';
    Exit;
  end;
  IPaddr := '';
  New(HName);
  if GetHostName(HName^, SizeOf(Name)) = 0 then
  begin
    HostName := StrPas(HName^);
    HEnt := GetHostByName(HName^);
    for i := 0 to HEnt^.h_length - 1 do
     IPaddr :=
      Concat(IPaddr,
      IntToStr(Ord(HEnt^.h_addr_list^[i])) + '.');
    SetLength(IPaddr, Length(IPaddr) - 1);
    Result := True;
  end
  else begin
   case WSAGetLastError of
    WSANOTINITIALISED:WSAErr:='WSANotInitialised';
    WSAENETDOWN      :WSAErr:='WSAENetDown';
    WSAEINPROGRESS   :WSAErr:='WSAEInProgress';
   end;
  end;
  Dispose(HName);
  WSACleanup;
end;

function GetIPFromHost(const HostName: string): string;
type
  TaPInAddr = array[0..10] of PInAddr;
  PaPInAddr = ^TaPInAddr;
var
  phe: PHostEnt;
  pptr: PaPInAddr;
  i: Integer;
  GInitData: TWSAData;
begin
  WSAStartup($101, GInitData);
  Result := '';
  phe := GetHostByName(PChar(HostName));
  if phe = nil then Exit;
  pPtr := PaPInAddr(phe^.h_addr_list);
  i := 0;
  while pPtr^[i] <> nil do
  begin
    Result := inet_ntoa(pptr^[i]^);
    Inc(i);
  end;
  WSACleanup;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit4.Text := IPAddrToName(Edit1.Text);
end;



procedure TForm1.Button2Click(Sender: TObject);
begin
  Edit3.Text := GetIPFromHost(Edit2.Text)
end;

procedure TForm1.Timer1Timer(Sender: TObject);
Var Host,IPs, ERs : String;
begin
  GetLocalIPFromHost(Host,IPs,ERs);
  GroupBox1.Caption := IPs ;
  label2.Caption:= IPs ;
end;

огрызок проги рабочий если подумаеш то сможэш переделать его в сканер
показывает ip на 100%
« Последнее редактирование: 20-12-2007 18:32 от Алексей1153++ » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines