Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Delphi network starting 1

Status
Not open for further replies.

jfreak53

IS-IT--Management
Apr 30, 2004
44
0
0
GT
I need to make a small program that checks certain ip addresses on my personal network every certain number of seconds to see if they are connected to the network, maybe a ping? I was told that Indy components have this feature but I cannot find it, I use delphi 6.
 
I have d6 enterprise. And it does come with indy, three tabs worth of it, but I don't know which component to use or how to use them, there is none that says ping.
 
This is the code I used and all it did was to return false all the time:

procedure TForm1.Button1Click(Sender: TObject);
begin
ping1.Ping;
end;

procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Status: Integer);
begin
if Status <> 0 then
{ Success }
label1.Caption := 'true'
else
{ Failure }
label1.caption := 'false';

end;

procedure TForm1.Ping1DnsLookupDone(Sender: TObject; Error: Word);
begin
if Error <> 0 then begin
label1.caption := 'false';
Exit;
end;
end;

 
I ran this and it runs fine:

unit PingU1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Controls, Forms,
StdCtrls, SI_Lib, Ping;

type
TForm1 = class(TForm)
Ping1: TPing;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Button1: TButton;
Label4: TLabel;
procedure Ping1EchoReply(Sender, Icmp: TObject; Error: Integer);
procedure Button1Click(Sender: TObject);
procedure Ping1DnsLookupDone(Sender: TObject; Error: Word);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation


{$R *.dfm}

procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Error: Integer);
begin
Label3.Caption := 'End ='+FnHHMMSS(True);
Label1.Caption := 'Status='+Str_(Error);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Label2.Caption := 'Start='+FnHHMMSS(True);
Ping1.DnsLookup('end;

procedure TForm1.Ping1DnsLookupDone(Sender: TObject; Error: Word);
begin
If (Error = 0) Then
Begin
Ping1.Address := Ping1.DNSResult;
Ping1.Ping;
End;
Label4.Caption := 'DNS-Done='+Str_(Error)+' '+Ping1.Address;
end;

end.

HTH,
JGS
 
Two problems with that script, one I don't want to check an address on the web, I want it to all be local: 192.168.0.1 etc. two when I use it to check addresses I know don't exist or aren't connected I still get status 0 no matter what??? And I don't really need to know the time taken to ping or anything else, all I need to know is whether or not it is connected???
 
J-

Well, all you would need to do is to replace

Ping1.Address := Ping1.DNSResult;

With

Ping1.Address := '192.168.0.1';

and put the

Ping1.Ping;

in the buttonclick. When I do that to my local net I get an error of 1, error 0 means it isn't responding (not there, not connected).

You don't need the dnslookupdone if you aren't resolving an 'http.....'

JGS
 
J-

If you want it in terms of your code then:

procedure TForm1.Button1Click(Sender: TObject);
begin
Ping1.Address := '192.168.0.1';
ping1.Ping;
end;

procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Status: Integer);
begin
if Status <> 0 then
{ Success }
label1.Caption := 'true'
else
{ Failure }
label1.caption := 'false';
end;


Of course my addresses on my local net are different than what you indicated, but I can ping my other computers with no problems...

JGS
 
Thanks I just didn't see it before, thanks for all your help.
 
I have a new question I would like another version of this software that will check the whole range of Network Ip's from 192.168.0.0 to 192.168.0.whatever to see which ones are connected, I don't want it to do it off of a list of sort, all I want to see is if there is any other new ip's on the network and I would like to do it kind of fast?
 
J-
Maybe something like this...
NOTE: I don't know if "hanging" in the I,J loop is going to stop the Ping1EchoReply loop.... I haven't got enough of a network here to check it out....

Code:
Var
  I, J       : Integer;
  ThereArray : Array[0..255, 0..255] of Boolean;
:
:
Procedure TForm1.Timer1Timer(....) // ????
Begin
  FillChar(ThereArray, Sizeof(ThereArray), False); // Assume none????

  For I := 0 to 255 Do
    For J := 0 to 255 Do
      Begin
        If (ThereArray(I, J) := True) Then
          Continue; // Skip it if it's there already???? Mutually exclusive with FillChar above

        Ping1.Address := '192.168.'+IntToStr(I)+'.'+IntToStr(J);
        Ping1.Ping;
      End;
End;

Procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Status: Integer);
begin
  if (Status <> 0) then
    ThereArray(I, J) := True
  else
    ThereArray(I, J) := False;
End;
Begin
// Unit init
  FillChar(ThereArray, SizeOf(ThereArray), False); //Alt clearing
end;


Regards and HTH,
JGS
 
Ok, I tried it and these are the error messages I got:

[Warning] Unit1.pas(34): For loop control variable must be simple local variable
[Warning] Unit1.pas(35): For loop control variable must be simple local variable
[Error] Unit1.pas(37): Missing operator or semicolon
[Error] Unit1.pas(47): Undeclared identifier: 'Status'
[Warning] Unit1.pas(47): Comparing signed and unsigned types - widened both operands
[Error] Unit1.pas(48): Missing operator or semicolon
[Error] Unit1.pas(49): Incompatible types: 'Array' and 'Boolean'
[Error] Unit1.pas(50): Missing operator or semicolon
[Error] Unit1.pas(50): Incompatible types: 'Array' and 'Boolean'
[Error] Unit1.pas(57): Record, object or class type required
[Error] Unit1.pas(59): 'END' expected but end of file found
[Error] Unit1.pas(14): Unsatisfied forward or external declaration: 'TForm1.Ping1EchoReply'
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'


This is my source:


var
Form1: TForm1;
I, J : Integer;
ThereArray : Array[0..255, 0..255] of Boolean;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
FillChar(ThereArray, Sizeof(ThereArray), False); // Assume none????

For I := 0 to 255 Do
For J := 0 to 255 Do
Begin
If (ThereArray(I, J) := True) Then
Continue; // Skip it if it's there already???? Mutually exclusive with FillChar above

Ping1.Address := '192.168.'+IntToStr(I)+'.'+IntToStr(J);
Ping1.Ping;
End;
end;

procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Status: Integer);
begin
if (Status <> 0) then
ThereArray(I, J) := True
else
ThereArray(I, J) := False;
End;
Begin
// Unit init
FillChar(ThereArray, SizeOf(ThereArray), False); //Alt clearing
end;
 
J-

Sorry, my "()" should have been "[]". The compiler complains about variables not being "local", but I do it all the time anyway.

Here is a "no error" version of your code.

Code:
uses
  Windows, Messages, SysUtils, Variants, Classes,  Controls, Forms,
  StdCtrls, Ping, ExtCtrls;

type
  TForm1 = class(TForm)
    Ping1: TPing;
    Button1: TButton;
    procedure Ping1EchoReply(Sender, Icmp: TObject; Error: Integer);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Idx1, Idx2 : Integer;
  ThereArray : Array[0..255, 0..255] of Boolean;

implementation


{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
  I, J  : Integer;
begin
  FillChar(ThereArray, Sizeof(ThereArray), False); // Assume none????

  For I := 0 to 255 Do
    For J := 0 to 255 Do
      Begin
        Idx1 := I;
        Idx2 := J;
        // The following statement really shouldn't be here
        // because ThereArray was just cleared OR don't clear
        // at the top of buttonclick
        If (ThereArray[I, J] = True) Then
          Continue; // Skip it if it's there already???? Mutually exclusive with FillChar above

        Ping1.Address := '192.168.'+IntToStr(I)+'.'+IntToStr(J);
        Ping1.Ping;
      End;
end;

procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Error : Integer);
begin
  if (Error <> 0) then
    ThereArray[Idx1, Idx2] := True
  else
    ThereArray[Idx1, Idx2] := False;
End;

Begin
// Unit init
  FillChar(ThereArray, SizeOf(ThereArray), False); //Alt clearing
end.

Regards and HTH,
JGS
 
Use FPiette components at drag Ping component on your form,
drag one Button on the form use ping1.Ping1EchoReply.
Here is all the unit:

Code:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Ping;

type
  TForm1 = class(TForm)
    Ping1: TPing;
    Button1: TButton;
    procedure Ping1EchoReply(Sender, Icmp: TObject; Status: Integer);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    pcConnected : boolean;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Status: Integer);
begin
  if status = 1 then pcConnected := true;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ping1.Address := '192.168.0.1';
  pcConnected := false;
  ping1.Ping;
end;

end.

I think this is the simplest form. And it works always !!! in lolcal network or internet.

Giovanni Caramia
 
J-

Awoke with a startling revelation that my last iteration of the code would not work because there was no "wait for reply" before the next ping.

This looks like a better way to handle it:

Code:
unit PingU1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes,  Controls, Forms,
  StdCtrls, Ping, ExtCtrls;

type
  TForm1 = class(TForm)
    Ping1: TPing;
    Button1: TButton;
    procedure Ping1EchoReply(Sender, Icmp: TObject; Error: Integer);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  Idx1, Idx2 : Integer;
  ThereArray : Array[0..255, 0..255] of Boolean;

implementation


{$R *.dfm}

Procedure Ping_IP;
Begin
  Form1.Ping1.Address := '192.168.'+IntToStr(Idx1)+'.'+IntToStr(Idx2);
  Form1.Ping1.Ping;
End;

procedure TForm1.Button1Click(Sender: TObject);
begin
  FillChar(ThereArray, Sizeof(ThereArray), False); // Assume none????
  Idx1 := 0;    // Reset
  Idx2 := 0;    // Reset
  Ping_IP;      // Kick off loop
end;

procedure TForm1.Ping1EchoReply(Sender, Icmp: TObject; Error : Integer);
begin
// If you put anything on the screen, this procedure should contain
//Application.ProcessMessages;
  if (Error <> 0) then
    ThereArray[Idx1, Idx2] := True
  else                               // Else not necessary if array cleared in buttonclick
    ThereArray[Idx1, Idx2] := False;

  If (Idx2 < 255) Then
    Inc(Idx2)
  Else
    Begin
      Inc(Idx1);
      Idx2 := 0;
    End;

  If (Idx1 <= 255) Then
    Ping_IP;  
End;

Begin
// Unit init
  FillChar(ThereArray, SizeOf(ThereArray), False); //Alt clearing
end.

Regards and HTH,
JGS
 
Ok, what do you mean by:

// If you put anything on the screen, this procedure should contain
//Application.ProcessMessages;

I have a label1 on the application screen how do I apply this?
 
J-

I meant by that statement that if you do "anything" to change the contents of "anything" on the form and you want to "see" it before the whole loop is finished, then you should have

Application.Processmessages;

in the loop... basically just remove the "//" from my sample "//Application.ProcessMessages" and you will be able to see the changes in your form, such as "seeing" the label1.caption change if you change it inside the loop otherwise there is not enough time allocated to the "main" form thread to update it...



Regards and HTH,
JGS
 
Ok, but how do I display it on the label the ips that are connected?
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top