Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Работа с сетью в Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 03.07.2012, 18:28   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию ICMP. Функция ping'а, возвращает код о недостатке ресурсов. ?

Доброго времени суток!

Пишу свою реализацию PING'а.
Написал функцию:
Код:
function PingThis(aAddress: string; aTimeout: Integer;
  var vStr: string): Boolean;

  function IP2Str(aIP: Integer): string;
  begin
    Result := IntToStr(LoByte(LoWord(aIP))) + '.' + IntToStr(HiByte(LoWord(aIP))
      ) + '.' + IntToStr(LoByte(HiWord(aIP))) + '.' +
      IntToStr(HiByte(HiWord(aIP)));
  end;

var
  hICMP: THandle;
  pReply: PIcmpEchoReply;
  Buff: array [0 .. 31] of Char;
  sckVerRequest: Word;
  sckError: Integer;
  sckData: WSAData;
  pSckHost: PHostEnt;
  sckDestAddr: in_addr;
begin
  Result := False;
  try
    hICMP := IcmpCreateFile;
    GetMem(pReply, SizeOf(TIcmpEchoReply) + SizeOf(Buff));
    pReply.Data := @Buff;
    pReply.DataSize := SizeOf(Buff);
    sckVerRequest := MakeWord(1, 1);
    sckError := WSAStartup(sckVerRequest, sckData);
    if not Boolean(sckError) then
    begin
      pSckHost := gethostbyname(PAnsiChar(AnsiString(aAddress)));
      sckError := GetLastError;
      if not Boolean(sckError) then
      begin
        sckDestAddr := PInAddr(pSckHost^.h_addr_list^)^;
        IcmpSendEcho(hICMP, sckDestAddr.S_addr, @Buff, SizeOf(Buff), nil,
          pReply, SizeOf(TIcmpEchoReply) + SizeOf(Buff), aTimeout);
        sckError := GetLastError;
        if not Boolean(sckError) then
        begin
          if pReply.Status = IP_SUCCESS then
          begin
            vStr := Format('Successful reply from %s[%s] RTT=%d',
              [aAddress, IP2Str(pReply.Address), pReply.RoundTripTime]);
            Result := True;
          end;
        end
        else
          vStr :='[ICMP STATUS: '+IntToStr(sckError)+'] '+SysErrorMessage(sckError);
      end
      else
        vStr := '[ICMP STATUS: '+IntToStr(sckError)+'] '+SysErrorMessage(sckError);
    end
    else
      vStr := '[ICMP STATUS: '+IntToStr(sckError)+'] '+SysErrorMessage(sckError);
  finally
    WSACleanup;
    FreeMem(pReply);
    IcmpCloseHandle(hICMP);
  end;
end;
Немогу понять, ночему не хочет работать.
Человек_Борща вне форума Ответить с цитированием
Старый 04.07.2012, 02:35   #2
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Хм... Повторить ошибку не смог. Пример перекомпилирова под ХЕ2. После обработки напильником все работает... Выкладываю весь текст, ибо лень. Обрати внимание на переменную sckDestAddr. Ну и на секцию Uses тоже.

Код:
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, jwaWinSock2, jwaIcmpApi, jwaIPExport,
  RzButton, Vcl.ImgList, Vcl.ExtCtrls, RzPanel;

type
  TForm1 = class(TForm)
    RzToolbar1: TRzToolbar;
    ImageList1: TImageList;
    BtnSkipForward: TRzToolButton;
    procedure BtnSkipForwardClick(Sender: TObject);
  private
   function PingThis(aAddress: string; aTimeout: Integer;  var vStr: string): boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TForm1 }

procedure TForm1.BtnSkipForwardClick(Sender: TObject);
var
   s: string;
begin
  if PingThis('212.122.1.2', 1000, s) then
  ShowMessage(s);
end;

function TForm1.PingThis(aAddress: string; aTimeout: Integer;
  var vStr: string): boolean;
function IP2Str(aIP: Integer): string;
begin
  Result := IntToStr(LoByte(LoWord(aIP))) + '.' + IntToStr(HiByte(LoWord(aIP))
    ) + '.' + IntToStr(LoByte(HiWord(aIP))) + '.' +
    IntToStr(HiByte(HiWord(aIP)));
end;

var
  hICMP: THandle;
  pReply: PIcmpEchoReply;
  Buff: array [0 .. 31] of Char;
  sckVerRequest: Word;
  sckError: Integer;
  sckData: WSAData;
  pSckHost: PHostEnt;
  sckDestAddr: LONGWORD;
begin
    Result := False;
  try
    hICMP := IcmpCreateFile;
    GetMem(pReply, SizeOf(TIcmpEchoReply) + SizeOf(Buff));
    pReply.Data := @Buff;
    pReply.DataSize := SizeOf(Buff);
    sckVerRequest := MakeWord(1, 1);
    sckError := WSAStartup(sckVerRequest, sckData);
    if not Boolean(sckError) then
    begin
      pSckHost := gethostbyname(PAnsiChar(AnsiString(aAddress)));
      sckError := GetLastError;
      if not Boolean(sckError) then
      begin
        sckDestAddr := LONGINT(pLONGINT(pSckHost^.h_addr_list^)^);
        IcmpSendEcho(hICMP, sckDestAddr, @Buff, SizeOf(Buff), nil,
          pReply, SizeOf(TIcmpEchoReply) + SizeOf(Buff), aTimeout);
        sckError := GetLastError;
        if not Boolean(sckError) then
        begin
          if pReply.Status = IP_SUCCESS then
          begin
            vStr := Format('Successful reply from %s[%s] RTT=%d',
              [aAddress, IP2Str(pReply.Address), pReply.RoundTripTime]);
            Result := True;
          end;
        end
        else
          vStr :='[ICMP STATUS: '+IntToStr(sckError)+'] '+SysErrorMessage(sckError);
      end
      else
        vStr := '[ICMP STATUS: '+IntToStr(sckError)+'] '+SysErrorMessage(sckError);
    end
    else
      vStr := '[ICMP STATUS: '+IntToStr(sckError)+'] '+SysErrorMessage(sckError);
  finally
    WSACleanup;
    FreeMem(pReply);
    IcmpCloseHandle(hICMP);
  end;

end;

end.
Баламут вне форума Ответить с цитированием
Старый 04.07.2012, 15:09   #3
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Гм. Всеравно непонимаю. Не хватает ему ресурсов...
С переменной sckDestAddr тоже проблем нет. В sckDestAddr.S_addr тоже значение что и при вашем способе, получается.

Я переводил ICMP API сам, так сказать чтобы одном файлом было, с MSDN.
Выкладываю весь проект.
Вложения
Тип файла: rar ArhICMP.rar (1.31 Мб, 17 просмотров)
Человек_Борща вне форума Ответить с цитированием
Старый 05.07.2012, 04:49   #4
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

Немного неверно функцию импортировал. Размер параметра не тот малость. Все не смотрел. Исправил лишь используемую в данном случае ф-ию.
Вложения
Тип файла: rar ArhICMP.rar (4.5 Кб, 15 просмотров)
Баламут вне форума Ответить с цитированием
Старый 05.07.2012, 23:48   #5
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Нет, не помогло к сожалению.
Проблема все таже, даже с исправлением из 2-го поста.
У вас работает проект с этим модулем?

Последний раз редактировалось Человек_Борща; 06.07.2012 в 21:29.
Человек_Борща вне форума Ответить с цитированием
Старый 11.07.2012, 01:25   #6
Баламут
Баламучу слегка...
Участник клуба
 
Аватар для Баламут
 
Регистрация: 01.11.2006
Сообщений: 1,585
По умолчанию

В том-то и петрушка, что все работает на ура.
Баламут вне форума Ответить с цитированием
Старый 26.09.2013, 02:11   #7
tarakan1983
Форумчанин
 
Аватар для tarakan1983
 
Регистрация: 09.09.2008
Сообщений: 418
По умолчанию

Доброго времени суток!
Использую Вашу функцию, но она у меня почему-то всегда в false, какой бы IP я не пинговал. Спотыкается на коде
Код:
if pReply.Status = IP_SUCCESS then
          begin
            vStr := Format('Successful reply from %s[%s] RTT=%d',
              [aAddress, IP2Str(pReply.Address), pReply.RoundTripTime]);
            Result := True;
          end;
У меня pReply.Status равен 0 а константа IP_SUCCESS=11000.
Что я делаю не так?
tarakan1983 вне форума Ответить с цитированием
Старый 26.09.2013, 10:16   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Вечером посмотрю. поищите на моём сайте, по слову ICMP. Там есть рабочая версия. Сейчас ссылку кинуть не могу.
Человек_Борща вне форума Ответить с цитированием
Старый 26.09.2013, 14:14   #9
tarakan1983
Форумчанин
 
Аватар для tarakan1983
 
Регистрация: 09.09.2008
Сообщений: 418
По умолчанию

Я первым делом наткнулся на эту функцию на Вашем сайте, но работать её так и не заставил.
tarakan1983 вне форума Ответить с цитированием
Старый 26.09.2013, 14:31   #10
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Вечером я заставлю =)) Сейчас прокся не пускает.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Функция не возвращает данные. Abuhamed JavaScript, Ajax 4 26.10.2011 10:33
Функция возвращает массив Рик Общие вопросы Delphi 5 22.03.2011 09:07
Функция Pos возвращает 0 gufon Общие вопросы Delphi 16 14.03.2011 22:10
функция не возвращает результат=( Chica Bond Общие вопросы C/C++ 14 03.12.2010 18:47
Функция не возвращает значения 2.0 Winlook PHP 1 10.05.2010 00:58