Bosh
Гость
|
|
« : 18-11-2003 11:55 » |
|
Как в Delphi опросить сеть на IP адреса.
|
|
|
Записан
|
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #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
Специалист
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
|
|
« Ответ #4 : 28-12-2004 13:44 » |
|
Где-то что-то верно, добавляю идею, что можно не в цикле, а во временно созданных N (например, 256-1) потоках (Threads). Получается быстрее (2-4 сек вместо много-много)
|
|
|
Записан
|
Мысли должны быть короткие и плоские. Так их в ROM больше помещается.
|
|
|
x77
Модератор
Offline
Пол:
меняю стакан шмали на обратный билет с Марса.
|
|
« Ответ #5 : 29-12-2004 22:33 » |
|
Allex, как ты себе представляешь работу машины с 255 одновременно установленными handshake'ами?
|
|
« Последнее редактирование: 21-11-2007 16:18 от Алексей1153++ »
|
Записан
|
|
|
|
x77
Модератор
Offline
Пол:
меняю стакан шмали на обратный билет с Марса.
|
|
« Ответ #6 : 29-12-2004 22:36 » |
|
открой на компе 255 окон интернет эксплорера и начни их грузить одновременно. грубо, конечно, но примерно так. кроме того, никто не сказал, что в сети доступна только текущая маска. сеть может состоять из нескольких рабочих групп / доменов, где маски будут разными. для 10 рабочих групп ты получишь 2550 возможных адресов, в твоём варианте это эквивалентно 2550 процессов.
|
|
|
Записан
|
|
|
|
Allex63
|
|
« Ответ #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
|
|
« Ответ #9 : 04-04-2005 09:05 » |
|
Skyhawk wrotes: Но ведь если сеть локальная, зачем пинговать весь диапазон адресов? Не проще получить спиок компьютеров и спросить у каждого его IP адрес - операция в один цикл.
RXL wrotes: Есть вероятность что и активная машина не откликнется - например если настроена не отвечать.
Allex: Вероятность, что настройка/настроение машины не отвечать при получении списка компьютеров выше, чем при прямом Ping. Например, у меня (у соседа по комнате и еще у кучки народа) ящик весьма "необщительный" и в списке просто не проявляется. А Ping приходится наружу отдавать...
|
|
|
Записан
|
Мысли должны быть короткие и плоские. Так их в ROM больше помещается.
|
|
|
Nilbog
Гость
|
|
« Ответ #10 : 18-08-2005 09:00 » |
|
вот кусок проги на опредиление хоста и 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++ »
|
Записан
|
|
|
|
|