因此,我正在尝试编写一个多线程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)时,每次我点击按钮检查连接时,结果都是正确的。
没有sleep(10),它大部分时间都有效,但有时结果是错误的,对于离线计算机会给我一个ping回显,而在线计算机则没有ping回显,好像ping回复没有分配到正确的线程。
任何评论或帮助都受欢迎。
----- 编辑/重要 -----
作为这个问题的一般跟进,@Darian Miller在这里 https://code.google.com/p/delphi-stackoverflow/开始了一个Google Code项目,这是一个工作基础。我将他的答案标记为“接受的答案”,但用户应参考这个开源项目(所有信用归属于他),因为它肯定会在未来得到扩展和更新。