У меня есть комната с 60 компьютерами/устройствами (40 компьютеров и 20 осциллографов Windows CE), и я хотел бы знать, кто и каждый жив, используя ping. Сначала я написал стандартный пинг (см. Здесь Delphi Indy Ping Error 10040), который теперь отлично работает, но требует времени, когда большинство компьютеров находятся в автономном режиме.
Итак, я пытаюсь написать MultiThread Ping, но я очень борюсь с ним. Я видел только очень мало примеров в Интернете, и никто не соответствовал моим потребностям, поэтому я сам пытаюсь написать его.
Я использую XE2 и Indy 10, и форма состоит только из памятки и кнопки.
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) находится в коде. Каждый раз, когда я нажимал кнопку, чтобы проверить соединения, результат был правильным.
Без сна (10) он работает "больше всего" времени, но несколько раз результат неверен, давая мне эхо-пинг на автономных компьютерах и не пинговое эхо на онлайн-компьютере, равно как и ответ на пинг не был назначен к правильной нити.
Любые комментарии или помощь приветствуются.
----- РЕДАКТИРОВАТЬ/ВАЖНО -----
Как общее продолжение этого вопроса, @Darian Miller начал Проект Google Code здесь https://code.google.com/p/delphi-stackoverflow/, который является рабочей основой. Я отмечаю его ответ как "принятый ответ", но пользователи должны ссылаться на этот проект с открытым исходным кодом (весь кредит принадлежит ему), поскольку он, несомненно, будет расширен и обновлен в будущем.