Узнать Ip по сетевому имени

  • Автор темы Ash_Comp
  • Дата начала
A

Ash_Comp

#1
Собственно вопрос в заголовке.
Программа имеет удаленную серверную и локальную клиентскую части. Нечто типа простенького RAdmin'а. Использую порт 7711. Сперва пошёл следующим путём формирую список компьютеров в сети и отправляю им команды.
Использую код:
Код:
function FillNetLevel(xxx: PNetResource; List: TListItems): Word;
type
PNRArr = ^TNRArr;
TNRArr = array[0..59] of TNetResource;
var
x: PNRArr;
tnr: TNetResource;
I: integer;
EntrReq,
SizeReq,
twx: THandle;
WSName: string;
LI: TListItem;

begin
Result := WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY,
RESOURCEUSAGE_CONTAINER, xxx, twx);
if Result = ERROR_NO_NETWORK then
Exit;
if Result = NO_ERROR then
begin
New(x);
EntrReq := 1;
SizeReq := SizeOf(TNetResource) * 59;
while (twx <> 0) and
(WNetEnumResource(twx, EntrReq, x, SizeReq) <> ERROR_NO_MORE_ITEMS) do
begin
for i := 0 to EntrReq - 1 do
begin
Application.ProcessMessages;
Move(x^[i], tnr, SizeOf(tnr));
case tnr.dwDisplayType of
RESOURCEDISPLAYTYPE_SERVER:
begin
if tnr.lpRemoteName <> '' then
WSName := tnr.lpRemoteName
else
WSName := tnr.lpComment;

LI := list.Add;
LI.Caption := copy(WSName, 3, length(WSName) - 2);
LI.ImageIndex := 9;
end 
else
FillNetLevel(@tnr, list);
end;
end;
end;
Dispose(x);
WNetCloseEnum(twx);
end;
end;
Отрабатывает и в ListView1 получаю список компьютеров. Теперь было бы неплохо по этим названиям узнать их IP-адреса.
Недавно накопал ещё один вариант: использовать сканер сети, который перебирает IP-адреса и находит компьютеры с открытым моей серверной частью портом 7711. Но можно умереть, пока код отработает:
Код:
procedure TForm1.Button8Click(Sender: TObject);
var
D:WSAData;
S:TSocket;
A:TSockAddr;
m1,m2,mask,val:String;
i:Integer;
begin
mask:='192.168.0';
//val:=paramstr(2);
{ Определяем диапазон сканирования}
m1:= '10';
m2:= '11';
Showmessage('- Scanning begin: '+mask+'.'+m1+' - '+mask+'.'+m2+' -');
//writeln;
{ Если WSAStartup() возвращает не нулевое значение, выводим сообщение об ошибке
и выходим из программы}
if WSAStartup($101,D)<>0 then
begin
Showmessage('error..');
exit;
end;
{ Начинаем процесс сканирования }
for i:= 0 to ListView1.Items.Count - 1 do
begin
{ Определяем тип семейства сокетов, и IP адрес для сканирования }
A.sin_family:=AF_INET;
A.sin_addr.S_addr:=d_addr(ListView1.Items.Item[i].Caption);
{ Создаем сокет }
S:=socket(AF_INET,SOCK_STREAM,0);
{ Если возвращено значение INVALID_SOCKET, выводим сообщение об ошибке }
if S=INVALID_SOCKET then
Showmessage('socket error');
{ Определяем порт (задается константой) }
A.sin_port:=htons(7711);
{ Пытаемся подконнектиться, если удачно - выводим сообщение, что порт открыт,
в другом случае - сообщение о том, что порт закрыт (или недоступен) }
if connect(S,A,sizeof(A))=0 then
begin
ListView1.Items.Item[i].ImageIndex := 14;
//Showmessage(LI.Caption + ' opened')
end else
begin
ListView1.Items.Item[i].ImageIndex := 9;
//Showmessage(LI.Caption +' closed');
end;
end;
{ Завершаем работу с сокетами }
WSACleanup;
//writeln;
Showmessage('- Scanning is completed -');
//end;
end;
Попутно возник вопрос: как корректно обработать ошибку синхронизации с сервером (например на компьютере, на который посылается команда, сервер не стоит или выключен). Вылетает куча окошек (10061, 10049 и т.д.). Всевозможные исключения не знаю как прицепить. Как не пристрою -- окошек, по-моему, только больше :rolleyes:
Какие будут предложения?