私は60台のコンピューター/デバイス(40台のコンピューターと20台のオシロスコープがWindows CEベース)を備えた部屋を持っていますが、pingを使用して誰もが生きているか知りたいです。最初に、標準のping(ここでDelphi Indy Ping Error 10040を参照)を作成しました。これは現在は正常に機能していますが、ほとんどのコンピューターがオフラインになると時間がかかります。
だから私がやろうとしているのはマルチスレッドPingを書くことですが、私はそれにかなり苦労しています。私はインターネット上でほんの少しの例しか見たことがなく、誰も私のニーズに合っていなかったので、私はそれを自分で書こうとしています。
XE2とIndy10を使用していますが、フォームはメモとボタンのみで構成されています。
unit Main;
interface
uses
Winapi.Windows, System.SysUtils, System.Classes, Vcl.Forms,
IdIcmpClient, IdGlobal, Vcl.StdCtrls, Vcl.Controls;
type
TMainForm = class(TForm)
Memo1: TMemo;
ButtonStartPing: TButton;
procedure ButtonStartPingClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TMyPingThread = class(TThread)
private
fIndex : integer;
fIdIcmpClient: TIdIcmpClient;
procedure doOnPingReply;
protected
procedure Execute; override;
public
constructor Create(index: integer);
end;
var
MainForm: TMainForm;
ThreadCOunt : integer;
implementation
{$R *.dfm}
constructor TMyPingThread.Create(index: integer);
begin
inherited Create(false);
fIndex := index;
fIdIcmpClient := TIdIcmpClient.Create(nil);
fIdIcmpClient.ReceiveTimeout := 200;
fIdIcmpClient.PacketSize := 24;
fIdIcmpClient.Protocol := 1;
fIdIcmpClient.IPVersion := Id_IPv4;
//first computer is at adresse 211
fIdIcmpClient.Host := '128.178.26.'+inttostr(211+index-1);
self.FreeOnTerminate := true;
end;
procedure TMyPingThread.doOnPingReply;
begin
MainForm.Memo1.lines.add(inttostr(findex)+' '+fIdIcmpClient.ReplyStatus.Msg);
dec(ThreadCount);
if ThreadCount = 0 then
MainForm.Memo1.lines.add('--- End ---');
end;
procedure TMyPingThread.Execute;
begin
inherited;
try
fIdIcmpClient.Ping('',findex);
except
end;
while not Terminated do
begin
if fIdIcmpClient.ReplyStatus.SequenceId = findex then Terminate;
end;
Synchronize(doOnPingReply);
fIdIcmpClient.Free;
end;
procedure TMainForm.ButtonStartPingClick(Sender: TObject);
var
i: integer;
myPing : TMyPingThread;
begin
Memo1.Lines.Clear;
ThreadCount := 0;
for i := 1 to 40 do
begin
inc(ThreadCount);
myPing := TMyPingThread.Create(i);
//sleep(10);
end;
end;
end.
私の問題は、「sleep(10)」のコメントを外すと機能するように見え、それなしでは機能しないように見えることです。これは確かに、私が書いたスレッドのポイントが欠落していることを意味します。
言い換えると。Sleep(10)がコードに含まれている場合。ボタンをクリックして接続を確認するたびに、結果は正しいものでした。
sleep(10)がないと、ほとんどの場合動作しますが、結果が間違って、オフラインコンピューターではpingエコーが発生し、オンラインコンピューターではpingエコーが発生しないことがあります。これは、ping応答が正しいものに割り当てられていないためです。スレッド。
コメントやヘルプは大歓迎です。
-----編集/重要-----
この質問の一般的なフォローアップとして、@DarianMillerはここ https://code.google.com/p/delphi-stackoverflow/でGoogleCodeプロジェクトを開始しました。これは実用的な基盤です。私は彼の回答を「承認済みの回答」としてマークしますが、将来確実に拡張および更新されるため、ユーザーはこのオープンソースプロジェクト(すべてのクレジットは彼に帰属します)を参照する必要があります。