Sockets, определение IP адреса по URL

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

Ответить
Polinom2686
незнакомец
Сообщения: 8
Зарегистрирован: 02.09.2009 02:01:29

Sockets, определение IP адреса по URL

Сообщение Polinom2686 »

Здравствуйте, пишу небольшое приложение для работы по интернету. Использую модуль Sockets.
В программе я в явном виде прописываю IP адрес сервера в интернете, но хотелось бы получать IP адрес по исходному URL сервера. Есть ли такая возможность в модуле Sockets? Или необходимо пользоваться сторонними модулями?
Kitayets
постоялец
Сообщения: 174
Зарегистрирован: 05.05.2010 21:15:24

Сообщение Kitayets »

не сторонними, а идущими в комплекте и являющимися частью FCL.

unit называется netdb

вот какой пример идёт в комплекте. думаю разберёшься:

Код: Выделить всё

{
    This file is part of the Free Pascal run time library.
    Copyright (c) 2003 by the Free Pascal development team

    test netdb unit, host part

    See the file COPYING.FPC, included in this distribution,
    for details about the copyright.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 **********************************************************************}
{$mode objfpc}
{$h+}

program testdns;

uses netdb,Sockets;

Procedure DumpHostEntry(Const H : THostEntry);

begin
  With H do
    begin
    Writeln('Name     : ',Name);
    Writeln('Addr     : ',HostAddrToStr(Addr));
    Writeln('Aliases  : ',Aliases);
    Writeln;
    end;
end;

Procedure TestAddr(Addr : string);

Var
  H : THostEntry;

begin
  If ResolveHostByAddr(StrToHostAddr(Addr),H) then
    DumpHostEntry(H)
  else
    Writeln('No entry for address ',Addr)
end;

Procedure TestName(Const N : string);

Var
  H : THostEntry;

begin
  If ResolveHostByName(N,H) then
    DumpHostEntry(H)
  else
    Writeln('No entry for hostname ',N)
end;

Var
  I,l : INteger;
  Ans : Array [1..10] of THostAddr;
  H   : THostAddr;
  NAns : Array[1..10] of String;



begin
  Writeln('Resolving name ');
  l:=ResolveName('db.wisa.be',Ans);
  Writeln('Got : ',l,' answers');
  For I:=1 to l do
    Writeln(i:2,': ',hostAddrtostr(Ans[i]));
  Writeln('Resolving address ');
  H:=StrtoHostAddr('212.224.143.202');
  L:=ResolveAddress(H,NAns);
  Writeln('Got : ',l,' answers');
  For I:=1 to l do
    Writeln(i:2,': ',NAns[i]);
  Writeln('ResolveHostByName:');
  testname('malpertuus.wisa.be');
  Writeln('ResolveHostByAddr:');
  testaddr('212.224.143.202');
end.

Polinom2686
незнакомец
Сообщения: 8
Зарегистрирован: 02.09.2009 02:01:29

Сообщение Polinom2686 »

Благодарю.
Kitayets
постоялец
Сообщения: 174
Зарегистрирован: 05.05.2010 21:15:24

Сообщение Kitayets »

посмотрел, модуль netdb доступен только на unix-ах. Если нужно для windows то смотри модуль resolve из той-же fcl-net.

вот минимальный пример (у меня на win7 64 работает):

Код: Выделить всё

program test_dns;

{$mode objfpc}{$H+}
{$IFDEF WIN64}
{$IMAGEBASE $400000}
{$ENDIF}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, resolve,
  Sockets {<- нужен здесь для HostAddrToStr} ;

var
  hrs: THostResolver;
  i: Integer;

begin

  { add your program here }
  hrs:= THostResolver.Create(nil);
  if hrs.NameLookup('google.com') then
  begin
     for i:= 0 to hrs.AddressCount - 1 do
         writeln(HostAddrToStr(hrs.Addresses[i]));
  end;
  readln;
  FreeAndNil(hrs);
end.


Добавлено спустя 1 минуту 47 секунд:
PS модуль resolve есть как для Windows, так и для UNIX-ов.
Red
незнакомец
Сообщения: 8
Зарегистрирован: 09.07.2014 13:37:07

Сообщение Red »

Здравствуйте, рабочий метод. Но в Linux он возвращает всего лишь 1 случайный ip адрес хоста. Есть ли более красивый метод получить все возможные ip для хоста (как это работает для windows), чем спам NameLookup(host) ?
Red
незнакомец
Сообщения: 8
Зарегистрирован: 09.07.2014 13:37:07

Сообщение Red »

Ism
как это должно помочь?
Перефразирую:

Код: Выделить всё

  if hrs.NameLookup('www.yandex.ru') then
  begin
     for i:= 0 to hrs.AddressCount - 1 do
         writeln(HostAddrToStr(hrs.Addresses[i]));
  end;

Данный кусок кода в ОС Windows выведет 4 ip
5.255.255.5
77.88.55.66
77.88.55.55
5.255.255.55
В Ubuntu он выводит только 1 ip.
Если сделать костыль и вызывать NameLookup например 20 раз, то можно выудить среди рандомно повторенных адресов все 4.
Вопрос есть ли более правильный метод?
Аватара пользователя
Ichthyander
энтузиаст
Сообщения: 701
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань
Контактная информация:

Сообщение Ichthyander »

Я использую для получения IP адреса домена класс TDNSSend из synapse.

Код: Выделить всё

function TDNSThread.Request: boolean;
begin
... ...
  if FDNS.DNSQuery(DomainNameFullAnsi, QTYPE_A, FResponse) then
  begin
    FRequestCode:=FDNS.RCode;
    if FResponse.Count>0 then
      FIP := FResponse[0]
... ...
end;

В коде использован только первый IP, то есть FResponse[0]. А вам, видимо, нужны будет все строки FResponses
Red
незнакомец
Сообщения: 8
Зарегистрирован: 09.07.2014 13:37:07

Сообщение Red »

Ichthyander писал(а):В коде использован только первый IP

Я на этом и погорел :) Спасибо, но не хочется тащить Synapse для одного лишь DNS
Аватара пользователя
Ichthyander
энтузиаст
Сообщения: 701
Зарегистрирован: 04.04.2007 08:32:43
Откуда: Астрахань
Контактная информация:

Сообщение Ichthyander »

Red писал(а):
Ichthyander писал(а):В коде использован только первый IP

Я на этом и погорел :) Спасибо, но не хочется тащить Synapse для одного лишь DNS

В моем случае нужен именно первый.
А что собственно такого страшного в synapse? ) Попробуйте подключить модуль DNSSend и посмотрите насколько КБ увеличится выходной файл. Думаю изменения будут небольшие. По-любому в проекту тащатся огромное количество всяких модулей и библиотек. +/- одна ни на что не повлияет. А Synapse кроссплатформенно и надежно )
Red
незнакомец
Сообщения: 8
Зарегистрирован: 09.07.2014 13:37:07

Сообщение Red »

Путем взвешивания всех за и против было решено распарсить результат работы утилиты host. Спасибо всем кто откликнулся
Ответить