D
dreamones
Unregistered / Unconfirmed
GUEST, unregistred user!
下面的这段代码是从网上抄来的....用来进行Ping操作
有点郁闷,当把这段代码放在主窗口单元时,勉强可以正常运行,但如果把它放在非主窗口单元时,却老出错.(我在主窗口中还新建了一个新窗口,代码就放在这窗口中).
还有一个问题,因为这段代码是抄来的,里面还有一些小问题,就是按'停止'按钮的时候,程序是把扫描停止下来了,但不知道是不是线程没释放,整个窗口就卡在那里,不接受任何消息!而且在扫描完毕的时候也是这样!
unit Scan;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
StdCtrls, ExtCtrls, ComCtrls, IdBaseComponent, IdComponent, IdRawBase,
IdRawClient, IdIcmpClient, Gauges, WinSock;//添加WinSock
type
TPingIP = class(TThread)
private
IPAddress: string;
IPEndAddress: string;
procedure PingAddress;
procedure IcmpReply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
protected
procedure Execute; override;
end;
TScanForm = class(TForm)
RadioButton1:TRadioButton;
RadioButton2:TRadioButton;
GroupBox1: TGroupBox;
GroupBox2:TGroupBox;
StartIp_LabE: TLabeledEdit;//起始IP
EndIp_LabE: TLabeledEdit;//终止IP
LabeledEdit1:TLabeledEdit;
LabeledEdit4:TLabeledEdit;
LabeledEdit5:TLabeledEdit;
CheckBox1:TCheckBox;
CheckBox2:TcheckBox;
StatusBar1:TStatusBar;
StartPing_Btn: TButton;//开始Ping按钮
StopPing_Btn: TButton;//停止Ping按钮
ClearIp_Btn: TButton;//清空信息列表
PingProc_GG: TGauge;
IpList_LisB: TListBox;//用来输入Ping操作信息
procedure StartPing_BtnClick(Sender: TObject);
procedure StopPing_BtnClick(Sender: TObject);
procedure ClearIp_BtnClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
PIP: TPingIP;
procedure SetStatus(BtnStatus: Boolean);
public
procedure PingIPTerminated(Sender: TObject);
end;
var
ScanForm: TScanForm;
implementation
{$R *.dfm}
//转换网络中的地址
function TransformAddr(const CurrInAddr: TInAddr): TInAddr;
var
sbx: char;
tmpInAddr: TInAddr;
begin
tmpInAddr := CurrInAddr;
sbx := tmpInAddr.S_un_b.s_b1;
tmpInAddr.S_un_b.s_b1 := tmpInAddr.S_un_b.s_b4;
tmpInAddr.S_un_b.s_b4 := sbx;
sbx := tmpInAddr.S_un_b.s_b2;
tmpInAddr.S_un_b.s_b2 := tmpInAddr.S_un_b.s_b3;
tmpInAddr.S_un_b.s_b3 := sbx;
result := tmpInAddr;
end;
//获得下一个IP地址
function NextIP(const IPAddr: string; Step: Integer = 1): string;
var
tmpInAddr: TInAddr;
begin
tmpInAddr.S_addr := Winsock.inet_addr(pchar(IPAddr));
tmpInAddr := TransformAddr(tmpInAddr);
tmpInAddr.S_addr := tmpInAddr.S_addr + Step;
tmpInAddr := TransformAddr(tmpInAddr);
result := Winsock.inet_ntoa(tmpInAddr);
end;
//获得两个IP地址之间的数量
function IPWidth(const BeginIP, EndIP: string): DWORD;
var
BInAddr, EInAddr: TInAddr;
begin
BInAddr.S_addr := Winsock.inet_addr(pchar(BeginIP));
EInAddr.S_addr := Winsock.inet_addr(pchar(EndIP));
result := TransformAddr(EInAddr).S_addr
- TransformAddr(BInAddr).S_addr + 1;
end;
//执行线程
procedure TPingIP.Execute;
begin
OnTerminate := ScanForm.PingIPTerminated;
PingAddress;
end;
procedure TPingIP.PingAddress;
var
i, ipcount: integer;
IPEnd: string;
thIcmp: TIdIcmpClient;
begin
thICMP := TIdIcmpClient.Create(nil);
try
thICMP.OnReply := ICMPReply;
thICMP.ReceiveTimeout := 50;
IPEnd := NextIP(IPEndAddress);
ipcount := 0;
while (IPAddress <> IPEnd) do
begin
thICMP.Host := IPAddress;
for i := 1 to 3 do
begin
if Terminated then
Break;
thICMP.Ping;
//Application.ProcessMessages;
end;
if Terminated then
Break;
ipcount := ipcount + 1;
ScanForm.PingProc_GG.Progress := ipcount;
IPAddress := NextIP(IPAddress);
end;
finally
thICMP.Free;
end;
end;
//ICMP控件中的事件
procedure TPingIP.IcmpReply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
var
sTime: string;
begin
if Terminated then Exit;
if (AReplyStatus.MsRoundTripTime = 0) then
sTime := '<1'
else
sTime := '=';
//显示给用户的信息
ScanForm.IpList_LisB.Items.Insert(0, Format('%d bytes from %s: icmp_seq=%d ttl=%d time%s%d ms',
[AReplyStatus.BytesReceived,
IPAddress, //AReplyStatus.FromIpAddress,
AReplyStatus.SequenceId,
AReplyStatus.TimeToLive,
sTime,
AReplyStatus.MsRoundTripTime]));
end;
procedure TScanForm.SetStatus(BtnStatus: Boolean);
begin
StartPing_Btn.Enabled := BtnStatus;
StopPing_Btn.Enabled := not BtnStatus;
ClearIp_Btn.Enabled := BtnStatus;
end;
//中断线程后的事件
procedure TScanForm.PingIPTerminated(Sender: TObject);
begin
PIP.Free;
PIP := nil;
SetStatus(True);
end;
procedure TScanForm.StartPing_BtnClick(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
try
PingProc_GG.MaxValue := IPWidth(StartIp_LabE.Text, EndIp_LabE.Text);
PingProc_GG.Progress := 0;
PIP := TPingIP.Create(True);
PIP.IPAddress := StartIp_LabE.Text;
PIP.IPEndAddress := EndIp_LabE.Text;
PIP.Resume;
SetStatus(False);
finally
Screen.Cursor := crDefault;
end;
end;
procedure TScanForm.StopPing_BtnClick(Sender: TObject);
begin
PIP.Terminate;
end;
procedure TScanForm.ClearIp_BtnClick(Sender: TObject);
begin
PingProc_GG.Progress := 0;
IpList_LisB.Items.Clear;
end;
procedure TScanForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=CaFree;
end;
end.
各位帮忙啊,问题解决马上给分......在线等待中!!!
谢谢!
有点郁闷,当把这段代码放在主窗口单元时,勉强可以正常运行,但如果把它放在非主窗口单元时,却老出错.(我在主窗口中还新建了一个新窗口,代码就放在这窗口中).
还有一个问题,因为这段代码是抄来的,里面还有一些小问题,就是按'停止'按钮的时候,程序是把扫描停止下来了,但不知道是不是线程没释放,整个窗口就卡在那里,不接受任何消息!而且在扫描完毕的时候也是这样!
unit Scan;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
StdCtrls, ExtCtrls, ComCtrls, IdBaseComponent, IdComponent, IdRawBase,
IdRawClient, IdIcmpClient, Gauges, WinSock;//添加WinSock
type
TPingIP = class(TThread)
private
IPAddress: string;
IPEndAddress: string;
procedure PingAddress;
procedure IcmpReply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
protected
procedure Execute; override;
end;
TScanForm = class(TForm)
RadioButton1:TRadioButton;
RadioButton2:TRadioButton;
GroupBox1: TGroupBox;
GroupBox2:TGroupBox;
StartIp_LabE: TLabeledEdit;//起始IP
EndIp_LabE: TLabeledEdit;//终止IP
LabeledEdit1:TLabeledEdit;
LabeledEdit4:TLabeledEdit;
LabeledEdit5:TLabeledEdit;
CheckBox1:TCheckBox;
CheckBox2:TcheckBox;
StatusBar1:TStatusBar;
StartPing_Btn: TButton;//开始Ping按钮
StopPing_Btn: TButton;//停止Ping按钮
ClearIp_Btn: TButton;//清空信息列表
PingProc_GG: TGauge;
IpList_LisB: TListBox;//用来输入Ping操作信息
procedure StartPing_BtnClick(Sender: TObject);
procedure StopPing_BtnClick(Sender: TObject);
procedure ClearIp_BtnClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
PIP: TPingIP;
procedure SetStatus(BtnStatus: Boolean);
public
procedure PingIPTerminated(Sender: TObject);
end;
var
ScanForm: TScanForm;
implementation
{$R *.dfm}
//转换网络中的地址
function TransformAddr(const CurrInAddr: TInAddr): TInAddr;
var
sbx: char;
tmpInAddr: TInAddr;
begin
tmpInAddr := CurrInAddr;
sbx := tmpInAddr.S_un_b.s_b1;
tmpInAddr.S_un_b.s_b1 := tmpInAddr.S_un_b.s_b4;
tmpInAddr.S_un_b.s_b4 := sbx;
sbx := tmpInAddr.S_un_b.s_b2;
tmpInAddr.S_un_b.s_b2 := tmpInAddr.S_un_b.s_b3;
tmpInAddr.S_un_b.s_b3 := sbx;
result := tmpInAddr;
end;
//获得下一个IP地址
function NextIP(const IPAddr: string; Step: Integer = 1): string;
var
tmpInAddr: TInAddr;
begin
tmpInAddr.S_addr := Winsock.inet_addr(pchar(IPAddr));
tmpInAddr := TransformAddr(tmpInAddr);
tmpInAddr.S_addr := tmpInAddr.S_addr + Step;
tmpInAddr := TransformAddr(tmpInAddr);
result := Winsock.inet_ntoa(tmpInAddr);
end;
//获得两个IP地址之间的数量
function IPWidth(const BeginIP, EndIP: string): DWORD;
var
BInAddr, EInAddr: TInAddr;
begin
BInAddr.S_addr := Winsock.inet_addr(pchar(BeginIP));
EInAddr.S_addr := Winsock.inet_addr(pchar(EndIP));
result := TransformAddr(EInAddr).S_addr
- TransformAddr(BInAddr).S_addr + 1;
end;
//执行线程
procedure TPingIP.Execute;
begin
OnTerminate := ScanForm.PingIPTerminated;
PingAddress;
end;
procedure TPingIP.PingAddress;
var
i, ipcount: integer;
IPEnd: string;
thIcmp: TIdIcmpClient;
begin
thICMP := TIdIcmpClient.Create(nil);
try
thICMP.OnReply := ICMPReply;
thICMP.ReceiveTimeout := 50;
IPEnd := NextIP(IPEndAddress);
ipcount := 0;
while (IPAddress <> IPEnd) do
begin
thICMP.Host := IPAddress;
for i := 1 to 3 do
begin
if Terminated then
Break;
thICMP.Ping;
//Application.ProcessMessages;
end;
if Terminated then
Break;
ipcount := ipcount + 1;
ScanForm.PingProc_GG.Progress := ipcount;
IPAddress := NextIP(IPAddress);
end;
finally
thICMP.Free;
end;
end;
//ICMP控件中的事件
procedure TPingIP.IcmpReply(ASender: TComponent;
const AReplyStatus: TReplyStatus);
var
sTime: string;
begin
if Terminated then Exit;
if (AReplyStatus.MsRoundTripTime = 0) then
sTime := '<1'
else
sTime := '=';
//显示给用户的信息
ScanForm.IpList_LisB.Items.Insert(0, Format('%d bytes from %s: icmp_seq=%d ttl=%d time%s%d ms',
[AReplyStatus.BytesReceived,
IPAddress, //AReplyStatus.FromIpAddress,
AReplyStatus.SequenceId,
AReplyStatus.TimeToLive,
sTime,
AReplyStatus.MsRoundTripTime]));
end;
procedure TScanForm.SetStatus(BtnStatus: Boolean);
begin
StartPing_Btn.Enabled := BtnStatus;
StopPing_Btn.Enabled := not BtnStatus;
ClearIp_Btn.Enabled := BtnStatus;
end;
//中断线程后的事件
procedure TScanForm.PingIPTerminated(Sender: TObject);
begin
PIP.Free;
PIP := nil;
SetStatus(True);
end;
procedure TScanForm.StartPing_BtnClick(Sender: TObject);
begin
Screen.Cursor := crHourGlass;
try
PingProc_GG.MaxValue := IPWidth(StartIp_LabE.Text, EndIp_LabE.Text);
PingProc_GG.Progress := 0;
PIP := TPingIP.Create(True);
PIP.IPAddress := StartIp_LabE.Text;
PIP.IPEndAddress := EndIp_LabE.Text;
PIP.Resume;
SetStatus(False);
finally
Screen.Cursor := crDefault;
end;
end;
procedure TScanForm.StopPing_BtnClick(Sender: TObject);
begin
PIP.Terminate;
end;
procedure TScanForm.ClearIp_BtnClick(Sender: TObject);
begin
PingProc_GG.Progress := 0;
IpList_LisB.Items.Clear;
end;
procedure TScanForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=CaFree;
end;
end.
各位帮忙啊,问题解决马上给分......在线等待中!!!
谢谢!