Delphi(XE2)Indy(10)多线程Ping [英] Delphi (XE2) Indy (10) Multithread Ping

查看:863
本文介绍了Delphi(XE2)Indy(10)多线程Ping的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个房间里有60台电脑/设备(40台电脑和20台基于Windows CE的示波器),我想知道哪一个都是使用ping的。首先我写了一个标准的ping(见这里 Delphi Indy Ping Error 10040 ),这是现在工作很好,但是大多数电脑离线时都要花上几个月的时间。



所以我想要做的是写一个MultiThread Ping,但我很挣扎。我只看过互联网上的例子,没有人匹配我的需求,所以我试着自己写。



我使用XE2和Indy 10和表单只是一个备忘录和一个按钮。

  unit Main; 

接口

使用
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
{私人声明}
public
{公开声明}
end;

type
TMyPingThread = class(TThread)
private
fIndex:integer;
fIdIcmpClient:TIdIcmpClient;
procedure doOnPingReply;
protected
procedure Execute;覆盖
public
构造函数Create(index:integer);
结束

var
MainForm:TMainForm;
ThreadCOunt:integer;

实现

{$ R * .dfm}

构造函数TMyPingThread.Create(index:integer);
begin
继承Create(false);

fIndex:= index;
fIdIcmpClient:= TIdIcmpClient.Create(nil);
fIdIcmpClient.ReceiveTimeout:= 200;
fIdIcmpClient.PacketSize:= 24;
fIdIcmpClient.Protocol:= 1;
fIdIcmpClient.IPVersion:= Id_IPv4;

//第一台电脑在adresse 211
fIdIcmpClient.Host:='128.178.26。'+ inttostr(211 + index-1);

self.FreeOnTerminate:= true;
结束

程序TMyPingThread.doOnPingReply;
begin
MainForm.Memo1.lines.add(inttostr(findex)+''+ fIdIcmpClient.ReplyStatus.Msg);
dec(ThreadCount);

如果ThreadCount = 0然后
MainForm.Memo1.lines.add('--- End ---');
结束

程序TMyPingThread.Execute;
开始
继承;

try
fIdIcmpClient.Ping('',findex);

结束;

而不是终止do
begin
如果fIdIcmpClient.ReplyStatus.SequenceId = findex then Terminate;
结束

同步(doOnPingReply);
fIdIcmpClient.Free;
结束

程序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);
结束
结束

结束。

我的问题是,当我取消注释睡眠(10)时,似乎工作,和似乎没有它没有工作。这确实意味着我在我写的线程中缺少一点。



换句话说。睡眠(10)在代码中。每次我点击按钮来查看连接结果是否正确。



没有睡眠(10),它是大部分的时间,但有些时间结果是错误的,给我离线计算机上的ping echo,在线计算机上没有ping回显,ping回复没有分配给正确的线程。



任何欢迎评论或帮助。



-----编辑/重要-----



作为对此问题的一般跟踪,@Darian Miller在此开始 Google代码项目 https://code.google.com/p/delphi-stackoverflow/ ,这是一个工作基础。我将他的答案标示为接受的答案,但用户应该参考这个开源项目(所有的信用都属于他),因为它将来肯定会被扩展和更新。

解决方案

Remy解释了问题...我想在Indy这样做一段时间,所以我发布了一个可能的解决方案,我刚刚把一个新的Google Code项目而不是在这里有很长的评论。这是一个首要的事情,让我知道如果你有一些更改要整合:
https://code.google.com/p/delphi-vault/



此代码有两种方式Ping ...多线程客户端在您的示例中,或使用简单的回调过程。写为Indy10及更高版本的Delphi。



您的代码最终将使用定义SynchronizedResponse方法的TThreadedPing后代:



pre> TMyPingThread = class(TThreadedPing)
protected
procedure SynchronizedResponse(const ReplyStatus:TReplyStatus);覆盖
结束

要消除一些客户端线程,代码变成如下:

 程序TfrmThreadedPingSample.butStartPingClick(Sender:TObject); 
begin
TMyPingThread.Create('www.google.com');
TMyPingThread.Create('127.0.0.1');
TMyPingThread.Create('www.shouldnotresolvetoanythingatall.com');
TMyPingThread.Create('127.0.0.1');
TMyPingThread.Create('www.microsoft.com');
TMyPingThread.Create('127.0.0.1');
结束

线程响应以同步方式调用:

  procedure TMyPingThread.SynchronizedResponse(const ReplyStatus:TReplyStatus); 
begin
frmThreadedPingSample.Memo1.Lines.Add(TPingClient.FormatStandardResponse(ReplyStatus));
结束


I have a room with 60 computers/devices (40 computers and 20 oscilloscopes Windows CE based) and I would like to know which and every one is alive using ping. First I wrote a standard ping (see here Delphi Indy Ping Error 10040), which is working fine now but takes ages when most computers are offline.

So what I am trying to do is to write a MultiThread Ping but I am quite struggling with it. I have seen only very few examples over the internet and no one was matching my needs, that's why I try to write it myself.

I use XE2 and Indy 10 and the form is only constitued of a memo and a button.

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.

My problem is that it "seems" to work when I uncomment the "sleep(10)", and "seems" not to be working without it. This for sure means I am missing a point in the threading I have written.

In other words. When Sleep(10) is in the code. Every time I clicked the button to get to check the connections the result was correct.

Without the sleep(10), it is working "most" of the time but some times the result is wrong giving me a ping echo on offline computers and no ping echo on online computer, as is the ping reply was not assigned to the correct thread.

Any comment or help is welcome.

----- EDIT / IMPORTANT -----

As a general follow up of this question, @Darian Miller started a Google Code project here https://code.google.com/p/delphi-stackoverflow/ which is a working basis. I mark his answer as the "accepted answer" but users should refer to this open source project (all the credit belongs to him) as it will surely be extended and updated in the future.

解决方案

Remy explained the problems... I've wanted to do this in Indy for a while so I posted a possible solution that I just put together to a new Google Code project instead of having a long comment here. It's a first-stab sort of thing, let me know if you have some changes to integrate: https://code.google.com/p/delphi-vault/

This code has two ways to Ping...multi-threaded clients as in your example, or with a simple callback procedure. Written for Indy10 and later versions of Delphi.

Your code would end up using a TThreadedPing descendant defining a SynchronizedResponse method:

  TMyPingThread = class(TThreadedPing)
  protected
    procedure SynchronizedResponse(const ReplyStatus:TReplyStatus); override;
  end;

And to fire off some client threads, the code becomes something like:

procedure TfrmThreadedPingSample.butStartPingClick(Sender: TObject);
begin
  TMyPingThread.Create('www.google.com');
  TMyPingThread.Create('127.0.0.1');
  TMyPingThread.Create('www.shouldnotresolvetoanythingatall.com');
  TMyPingThread.Create('127.0.0.1');
  TMyPingThread.Create('www.microsoft.com');
  TMyPingThread.Create('127.0.0.1');
end;

The threaded response is called in a synchronized method:

procedure TMyPingThread.SynchronizedResponse(const ReplyStatus:TReplyStatus);
begin
  frmThreadedPingSample.Memo1.Lines.Add(TPingClient.FormatStandardResponse(ReplyStatus));
end;

这篇关于Delphi(XE2)Indy(10)多线程Ping的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆