Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2006.09.03;
Скачать: [xml.tar.bz2];

Вниз

Помогите пожалуйста с проверкой на наличие компа в сети   Найти похожие ветки 

 
Jah182100Jah ©   (2006-03-27 22:58) [0]

Люди добрые... поготи хто может, есть такая проблемка, необходимо сканить локальную сетку на наличие компов по 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 := "";
end;

Но с ней все делается очччеееенннньььь долго, если сканить всю подсеть то около 20 минут... А хотелось бы побыстрее :)
Кто-нибудь знает как енто обойти???


 
Eraser ©   (2006-03-28 00:44) [1]


> Jah182100Jah ©   (27.03.06 22:58)

так ф-я которую ты привёл совершенно другую задачу выполняет...
Решение - пинговать компы.


 
Jah182100Jah ©   (2006-03-28 08:02) [2]

Ну насчет того что другую..., енто я согласен, она получает имя компа в сети по ip, но ежели имени нет, то и компа нету (почти всегда :) ), а насчет пингования... если честно я не вкурсе, как это сделать средствами делфи!!!
Ежели подскажешь буду очень благодарен!!!


 
Alarm ©   (2006-03-28 10:29) [3]

http://www.delphimaster.ru/articles/netmon/index.html


 
Jah182100Jah ©   (2006-03-28 10:34) [4]

Оооо, спасибо, буду читать... как тока на работе время появится... или до дома придется терпеть))))


 
diMAN ©   (2006-03-28 10:35) [5]

В своё время я тоже с этим намучился. Вначале пробовал получить имена именно этим способом (через gethostbyaddr). Затем решил посмотреть сниффером как получает имена компьютеров программа Netbios Share Scaner, а делает это она ОЧЕНЬ быстро (255 компов пробегает менее чем за 2 сек. и выдаёт помимо ip и имя машины также MAC и имя залогиненного пользователя, правда последнее не всегда). Так вот эта программа для получения имени посылает netbios-запрос. Разбираться с netbios мне было особо некогда, поэтому я ограничился просто посылкой пакета и приёмом ответа. Но у меня в отличие от Netbios Share Scaner не всегда отображает имена из-за кривизны реализации. Вот мой код, может пригодится, хотя по-правильному нужно писать именно через обращение к netbios.


unit NBTStat;

interface

uses Windows;

type
 TMAC = array [1..6] of byte;
 PMAC = ^TMAC;

 TNBTStat = packed record
   ComputerName : String;
   GroupName    : String;
   UserName     : String;
   MAC          : TMAC;
   MACAddress   : String;
 end;
 PNBTStat = ^TNBTStat;

function GetNBTStat(lpIPAddress: String; var lpStat: TNBTStat): boolean; overload;

function GetNBTStat(dwIPAddress: DWORD; var lpStat: TNBTStat): boolean; overload;

implementation

uses NetRFC, WinSock, SysUtils;

function WaitForEchoReply(s: TSOCKET): integer;
var
Timeout: timeval;
readfds: Tfdset;
begin
 readfds.fd_count    := 1;
 readfds.fd_array[0] := s;
 Timeout.tv_sec      := 0;
 Timeout.tv_usec     := 100;

 Result := Select(1, @readfds, nil, nil, @Timeout);
end;

function GetNBTStat(lpIPAddress: String; var lpStat: TNBTStat): boolean;
begin
 Result := GetNBTStat(inet_addr(PChar(lpIPAddress)), lpStat);
end;

function GetNBTStat(dwIPAddress: DWORD; var lpStat: TNBTStat): boolean;
var
   sockRaw : TSocket;
   dest    : TSockAddrIn;
   from    : TSockAddrIn;
   netbios : NetBiosHeader;
   timeout : integer;
   bread   : integer;
   bwrote  : integer;
   recvbuf : pointer;
   fromlen : integer;
   i       : integer;
begin
 Result := False;
 
 with lpStat do
 begin
   ComputerName := "";
   GroupName    := "";
   UserName     := "";
   MACAddress   := "";
   ZeroMemory(@MAC, SizeOf(MAC));
 end;

 sockRaw := Socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);

 ZeroMemory(@dest, SizeOf(dest));
 with dest do
 begin
   sin_family      := AF_INET;
   sin_port        := htons(137);
   sin_addr.S_addr := dwIPAddress;
 end;

 ZeroMemory(@netbios, SizeOf(netbios));
 with netbios do
 begin
   TrID          := htons($29);
   Flags         := htons($10);
   Questions     := htons($01);
   AnswerRRs     := 0;
   AuthorityRRs  := 0;
   AdditionalRRs := 0;

   FillChar(Queries_Name, 34, #$41); // $20 $43 $4b $41 ... $00; bytes 34

   Queries_Name[1]  := $20;
   Queries_Name[2]  := $43;
   Queries_Name[3]  := $4b;
   Queries_Name[34] := $00;
   Queries_Type     := htons($21); // NBSTAT
   Queries_Class    := htons($01); // INET
 end;
{
 timeout := 1;
 bread   := SetSockOpt(sockRaw, SOL_SOCKET, SO_RCVTIMEO, PChar(@timeout), SizeOf(timeout));
 if bread = SOCKET_ERROR then Exit;

 timeout := 1;
 bread   := SetSockOpt(sockRaw, SOL_SOCKET, SO_SNDTIMEO, PChar(@timeout), SizeOf(timeout));
 if bread = SOCKET_ERROR then Exit;
}
 bwrote  := SendTo(sockRaw, netbios, SizeOf(netbios), 0, dest, SizeOf(dest));
 if bwrote = SOCKET_ERROR then Exit;

 bread   := WaitForEchoReply(sockRaw);
 if (bread = SOCKET_ERROR) or (bread = 0) then Exit;

 GetMem(recvbuf, MAX_PACKET);
 ZeroMemory(recvbuf, MAX_PACKET);
 fromlen := SizeOf(from);
 bread   := RecvFrom(sockRaw, recvbuf^, MAX_PACKET, 0, from, fromlen);
 if bread = SOCKET_ERROR
 then begin
   FreeMem(recvbuf);
   Exit;
 end;

 with NetBios_NameService_Responce(recvbuf^), lpStat do
 begin
   ComputerName := String(Answer_Name1);
   for i := 1 to Answer_NumOfNames - 1 do
   begin
     if (Names[i].NameType = 0) and (Names[i].NameFlags = $44)
       then GroupName := String(Names[i].Name);
     if (Names[i].NameType = 3) {and (Names[i].NameFlags = $44)}
       then UserName := String(Names[i].Name);
   end;
   MAC := PMAC(@Names[Answer_NumOfNames].Name)^;
   MACAddress := Format("%.2x-%.2x-%.2x-%.2x-%.2x-%.2x", [MAC[1], MAC[2], MAC[3], MAC[4], MAC[5], MAC[6]]);
 end;

 FreeMem(recvbuf);
 
 Result := True;
end;

end.


 
Rouse_ ©   (2006-03-28 10:36) [6]

Тут лучше чуть урезанную версию вот этого кода использовать:
http://rouse.front.ru/fastscan.zip
Просто в коде отключить сканирование ресурсов и делать завершение потока при нахождении имени ресурса...


 
diMAN ©   (2006-03-28 10:45) [7]

Да, вот ещё, забыл


unit NetRFC;

interface

type
NetBiosHeader = packed record
  TrID          : word;
  Flags         : word;
  Questions     : word;
  AnswerRRs     : word;
  AuthorityRRs  : word;
  AdditionalRRs : word;
  Queries_Name  : array [1..34] of byte;
  Queries_Type  : word;
  Queries_Class : word;
end;

NBName = packed record
 NameFlags : word;
 Name      : array [1..15] of char;
 NameType  : byte;
end;

NetBios_NameService_Responce = packed record
  TrID          : word;
  Flags         : word;
  Questions     : word;
  AnswerRRs     : word;
  AuthorityRRs  : word;
  AdditionalRRs : word;
  Answer_Name   : array [1..34] of byte;
  Answer_Type   : word;
  Answer_Class  : word;
  Answer_TTL    : dword;
  Answer_DataLenght : word;
  Answer_NumOfNames : byte;
  Answer_Name1      : array [1..15] of char;
  Answer_Name1Type   : byte;
  Names : array [1..1] of NBName;
end;

implementation
end.


 
Jah182100Jah ©   (2006-03-28 12:57) [8]

Всем откликнувшимся на мою проблему ОГРОМНОЕ спасибо... будет чем заняться вечерком))), надеюсь получится... об результате обязуюсь отписаться)))


 
EarlVadim ©   (2006-04-19 09:47) [9]

Rouse_ прислал великолепный работающий образец сканера по IP.

У меня несколько другая проблема.

У меня есть список сетевых имен компьютеров, а не их IP.
Как в этом случае быстро узнать, какие из них в данный момент работают?


 
Rouse_ ©   (2006-04-19 10:20) [10]


> Как в этом случае быстро узнать, какие из них в данный момент
> работают?

Получить IP каждого компьютера через gethostbyname и по аналогии...


 
EarlVadim ©   (2006-04-19 10:32) [11]

щас попробую, но в любом случае - спасибо... :beer:


 
Чапаев ©   (2006-04-19 12:38) [12]


>  WSAStartup($101, WSAData);

1. Зачем это делать внутри функции?
2. А WsaCleanup() вызывать Пушкин будет?


 
EarlVadim ©   (2006-04-19 17:01) [13]

2Rouse_

Там все ещё проще оказалось.
Достаточно


For i:= 1 to HOSTCount do BEGIN
   EXIST[i]:= false;
   if NetShareEnum(StringToOleStr(NAME[i]), 1, Info, DWORD(-1), @entriesread,
                      @totalentries, nil) = 0 then
   try
         if entriesread > 0 then EXIST[i]:= true;
   finally
         NetApiBufferFree(Info);
   end;
END;



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2006.09.03;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.053 c
15-1154425746
Nic
2006-08-01 13:49
2006.09.03
"Другие новости" на первом


2-1155488915
Berezne
2006-08-13 21:08
2006.09.03
Как для Combobox присвоить начальное значение?


2-1155632879
rym
2006-08-15 13:07
2006.09.03
Глупо


2-1155462065
Creater
2006-08-13 13:41
2006.09.03
Странный глюк


15-1155219308
top12
2006-08-10 18:15
2006.09.03
Подскажите windows socks server





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский