Модераторы: Snowy, Poseidon, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как сделать Hostname -> IP быстро? или переделать готовое решение... 
:(
    Опции темы
wesadex
Дата 21.6.2005, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 83
Регистрация: 21.6.2005

Репутация: нет
Всего: нет



Есть функция:
Код

function HostToIP(Name: string; var Ip: string): Boolean; 
var 
  wsdata : TWSAData; 
  hostName : array [0..255] of char; 
  hostEnt : PHostEnt; 
  addr : PChar; 
begin 
  WSAStartup ($0101, wsdata); 
  try 
    gethostname (hostName, sizeof (hostName)); 
    StrPCopy(hostName, Name); 
    hostEnt := gethostbyname (hostName); 
    if Assigned (hostEnt) then 
      if Assigned (hostEnt^.h_addr_list) then begin 
        addr := hostEnt^.h_addr_list^; 
        if Assigned (addr) then begin 
          IP := Format ('%d.%d.%d.%d', [byte (addr [0]), 
          byte (addr [1]), byte (addr [2]), byte (addr [3])]); 
          Result := True; 
        end 
        else 
          Result := False; 
      end 
      else 
        Result := False 
    else begin 
      Result := False; 
    end; 
  finally 
    WSACleanup; 
  end 
end; 



как видно она "делает" стринговый IP из имени хоста. Вопрос: как сделать так, чтобы это "чудо техники" заработало пошустрее, а то один-два хоста она отрабатывает быстро, а когда кол-во обработок достигает 500-700 - это великие тормоза даже на выделенке. Может стоит использовать какие-либо другие методы или принципы работы... к сожалению в этом не сильно силен, если кто знает - подскажите хотя бы где рыть землю... Спасибо заранее!


PM MAIL   Вверх
RA
Дата 22.6.2005, 02:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

Репутация: 10
Всего: 115



Цитата(wesadex @ 21.6.2005, 13:53)
Вопрос: как сделать так, чтобы это "чудо техники" заработало пошустрее


Никак, тут скорость зависит от функции gethostbyname встроенной в модуль Winsock.

Такчто, скорость тут максимальная.


Если у тебя много хостов, что тебе мешает обрабатывать их тойже функцией но в несколько потоков.
PM   Вверх
wesadex
Дата 22.6.2005, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 83
Регистрация: 21.6.2005

Репутация: нет
Всего: нет



Да в общем-то ничего, кроме одной маленькой, но неприятной фичи... когда число запросов выросло до 800-1500 в секунду родной ДНС улегся, таким же образом чуть не положил ДНСы провайдера... а так все Окей! Выход я вижу только в кэшировании запросов, но и тут облом... список хостов ОЧЕНЬ разнообразен, т.е. повторяется там только Тындекс и местный сайт, да при том это все еще и на лету надо делать...
PM MAIL   Вверх
RA
Дата 22.6.2005, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Брутальный буратина
****


Профиль
Группа: Участник Клуба
Сообщений: 3497
Регистрация: 31.3.2002
Где: Лес

Репутация: 10
Всего: 115



Цитата(wesadex @ 22.6.2005, 09:30)
запросов выросло до 800-1500


Это очень жестко, я себе позволилбы максимум 20.
PM   Вверх
jonimimoni
Дата 3.8.2008, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 10
Регистрация: 28.9.2007

Репутация: нет
Всего: нет



Похожий вопрос. Функцию взял в ДКРБ:
Код

function GetNameFromIP(const IP: String): String;
const
ERR_INADDR    = 'Can not convert IP to in_addr.';
ERR_HOST      = 'Can not get host information.';
ERR_WSA       = 'Can not initialize WSA.';
var
WSA   : TWSAData;
Host  : PHostEnt;
Addr  : u_long;
Err   : Integer;
begin
Result := 'noname';
Err := WSAStartup($101, WSA);
if Err <> 0 then
begin
   {$IFNDEF NO_MESSAGE}
     MessageDlg(ERR_WSA, mtError, [mbOK], 0);
   {$ENDIF}
   Exit;
end;
try
   Addr := inet_addr(PChar(IP));
   if Addr = u_long(INADDR_NONE) then
   begin
     {$IFNDEF NO_MESSAGE}
     MessageDlg(ERR_INADDR, mtError, [mbOK], 0);
     {$ENDIF}
     Exit;
   end;
   Host := gethostbyaddr(@Addr, SizeOf(Addr), PF_INET);
   if Assigned(Host) then
     Result := Host.h_name
   {$IFNDEF NO_MESSAGE}
//   else
//     MessageDlg(ERR_HOST, mtError, [mbOK], 0)
   {$ENDIF}
   ;
finally
   WSACleanup;
end;
end;

Список из 20 IP, пытаюсь получить имена хостов. Хосты под виндой и линухом возвращают имена очень резво, а вот есть програмируемые свичи с IP, которые имён не имеют. В них то и загвоздка, программа зависает на 2-3 минуты. Как видно из кода сообщение об ошибке я отключил (закоментировал), выводилось 'Can not get host information.', но это не выход, время на опрос слишком большое.
В связи с этим вопрос: Как сократить время опроса хостов без имени? Как сюда придумать параметр с таймаутом? Или если он тут есть - пролейте свет...

PM MAIL   Вверх
Poseidon
Дата 5.8.2008, 17:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 4
Всего: 133



Цитата(jonimimoni @  3.8.2008,  17:09 Найти цитируемый пост)
Как сюда придумать параметр с таймаутом?
Запускаешь поток-сканер и поток-ревизор. Если поток-сканер не завершается... ну... секунд 5 (следишь за временем в ревезоре), то потоком-ревизором завершаешь его и запускаешь сканирование другог хоста. Я бы так сделал.



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
jonimimoni
Дата 6.8.2008, 10:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 10
Регистрация: 28.9.2007

Репутация: нет
Всего: нет



Цитата(Poseidon @  5.8.2008,  17:56 Найти цитируемый пост)
Запускаешь поток-сканер и поток-ревизор.

Я не сомневаюсь в справедливости такого метода, но я самостоятельно такого не осилю. Моих знаний хватает на красивое расставление компонент на форме да склеивания кусков кода написанных другими. Хотелось бы увидеть код, в котором реализован этот метод.
ЗЫ: Извиняюсь за дерзость, но с сетью "играюсь" впервые...
PM MAIL   Вверх
Qu1nt
Дата 6.8.2008, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 602
Регистрация: 13.1.2007

Репутация: 2
Всего: 50



Собственно, если хочешь научится чему-то большему - делай сам. А мы подскажем и исправим.
PM MAIL   Вверх
jonimimoni
Дата 6.8.2008, 12:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Awaiting Authorisation
Сообщений: 10
Регистрация: 28.9.2007

Репутация: нет
Всего: нет



Цитата(Qu1nt @  6.8.2008,  10:58 Найти цитируемый пост)
Собственно, если хочешь научится чему-то большему - делай сам. А мы подскажем и исправим.

Я хочу, но знаний для этого маловато... С потоками вообще незнаком и незнаю ка реализовать.
Вот код процедуры, где происходит проверка\получение имени:
Код

procedure chping(ch : TCheckBox; pic : TImage; lab : TLabel);
var code, tout : integer;
    s, HostName : string;
begin
  if ch.Checked then
    begin
      form1.IdIcmpClient1.Host:=Lab.Caption;
      val(ReadIniData('Setting', 'TOut'), tout, code);
      form1.IdIcmpClient1.ReceiveTimeout:=tout;
      form1.IdIcmpClient1.Ping;

      if form1.IdIcmpClient1.ReplyStatus.TimeToLive <> 0 then {Ping +}
        begin
          pic.Picture.LoadFromFile('IMG\ON.bmp');
          if form1.CheckBox21.Checked then      {Name +}
            begin
              HostName := GetNameFromIP(lab.Caption);
              Delete(HostName, Pos('.', HostName), Length(HostName)-Pos('.', HostName)+1);
              s:=HostName;
            end else     {Name -}
            begin
              str(form1.IdIcmpClient1.ReplyStatus.TimeToLive, s);
              s:='TTL='+s;
            end;
          Ch.Caption:=s;
       end else    {Ping -}
       pic.Picture.LoadFromFile('IMG\Off.bmp');
    end else
    Pic.Picture.LoadFromFile('IMG\Clear.bmp');
end;

Как я понимаю строчка
Код

...
      form1.IdIcmpClient1.Ping;
...

и образует тот самый поток, но как организовать в два или более потока, и как самое главное их склонить к взаимодействию - это за пределами моих познаний.
PM MAIL   Вверх
Poseidon
Дата 6.8.2008, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 4
Всего: 133



О потоках нам все разжувал Петрович. За что ему и спасибо. Читаем


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Сети"
Snowy
Poseidon
MetalFan

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Snowy, Poseidon, MetalFan.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.0572 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.