5

ping を実行してコンピューターが稼働しているかどうかを確認する小さなコードがあります。以前は 40 台のコンピューターを備えた部屋があり、自分のプログラムを使ってリモートでチェックしたいと思っています。

そのため、indyを使用して少しping関数を書​​きました

function TMainForm.Ping(const AHost : string) : Boolean;
var
  MyIdIcmpClient : TIdIcmpClient;
begin
  Result := True;

  MyIdIcmpClient := TIdIcmpClient.Create(nil);
  MyIdIcmpClient.ReceiveTimeout := 200;
  MyIdIcmpClient.Host := AHost;

  try
    MyIdIcmpClient.Ping;
    Application.ProcessMessages;
  except
    Result := False;
    MyIdIcmpClient.Free;
    Exit;
  end;
  if MyIdIcmpClient.ReplyStatus.ReplyStatusType <> rsEcho Then result := False;

  MyIdIcmpClient.Free;
end;

だから私はそれを自宅のwifiネットワークで開発しましたが、すべてうまくいきます。

仕事に戻ってテストしたところ、次のエラーが表示されました

Socket Errod # 10040 Message too long

職場では固定 IP を使用しており、すべてのコンピューターと私は同じサブネット内にあります。

私は固定IPから切断し、もちろん同じサブネットではなくDHCPであるwifiに接続しようとしましたが、うまく機能しています。

このエラーとその解決方法をインターネットで検索しようとしましたが、多くの情報が見つかりませんでした。

もちろん、デフォルトのバッファ サイズをより大きな値に変更しようとしましたが、何も変更されず、同じサブネット内の固定 IP でエラーが発生します。

さらに、これが解決策を見つけるのに役立つかどうかはわかりませんが、私のコードは例外を扱いますが、その場合、タイムアウトが 200 ミリ秒に設定されているのに対し、エラーが発生するまでに約 3 ~ 4 秒かかります。そして、各pingでそれほど長く待つことはできません.

ちなみに、私はdelphi 2010を使用していますが、それはindy 10だと思います。XE2でもテストしましたが、同じエラーです。

何か案が

- - - 編集 - - -

この質問に回答しました。今、これをマルチスレッドで実行しようとしています。そのDelphi (XE2) Indy (10) Multithread Pingについて別の質問をしました。

4

3 に答える 3

7

PacketSizeプロパティを24次のように設定します。

function TMainForm.Ping(const AHost : string) : Boolean;
var
  MyIdIcmpClient : TIdIcmpClient;
begin
  Result := True;

  MyIdIcmpClient := TIdIcmpClient.Create(self);
  MyIdIcmpClient.ReceiveTimeout := 200;
  MyIdIcmpClient.Host := AHost;
  MyIdIcmpClient.PacketSize := 24;
  MyIdIcmpClient.Protocol := 1;
  MyIdIcmpClient.IPVersion := Id_IPv4;

  try
    MyIdIcmpClient.Ping;
    // Application.ProcessMessages; // There's no need to call this!
  except
    Result := False;
    Exit;
  end;
  if MyIdIcmpClient.ReplyStatus.ReplyStatusType <> rsEcho Then result := False;

  MyIdIcmpClient.Free;
end;
于 2012-10-04T09:03:31.453 に答える
1

XE5 と Indy10 の場合、パケット サイズが異なっていても、これは依然として問題です。

より不可解な修正に答えるには:

ABuffer := MyIdIcmpClient1.Host + StringOfChar(' ', 255);

これは、Indy10 コンポーネントにバグがあるという事実を回避するための「魔法の」修正です (私が Remy Lebeau を正しく理解していれば)。

私の推測では、これは受信バッファのサイズと何らかの関係があるということです。私の理論をテストするために、任意の文字を使用でき、ホスト アドレスを含める必要はまったくありません。受信バッファに必要な数の文字のみを使用してください。この小さなコード (C++ Builder XE5) を使用して Ping を実行し、大きな成功を収めました (他のすべての値はデフォルトのまま)。

AnsiString Proxy = StringOfChar('X',IcmpClient->PacketSize);

IcmpClient->Host = Host_Edit->Text;
IcmpClient->Ping(Proxy);

ご覧のとおり、PacketSize プロパティと同じ長さの文字列を作成します。あなたがそれを埋めるものは重要ではありません。

たぶん、これは @RemyLebeau が修正に取り組むときに役立つ可能性があります。

于 2014-02-10T03:10:37.907 に答える
0

このコードを使用してください

ABuffer := MyIdIcmpClient1.Host + StringOfChar(' ', 255);

MyIdIcmpClient.Ping(ABuffer);

于 2014-01-22T13:38:56.323 に答える