Delphi知识中心
www.delphi.ee
提供Delphi技术知识
与Delphi程序员共同进步


在线服务QQ:99923144 随时恭候您的光临
首页 基础知识 WIN系统 组件使用 组件开发 数据库 ACTIVEX 多媒体技术 网络技术 关于
文章类别:网络技术    你尚未登陆,会员功能无法使用,请从 网站首页 登陆。
  用Delphi实现专线状态的探测  
 

用Delphi实现专线状态的探测

随着计算机用户的增多,计算机网络越来越复杂,如何进行实时的网络检测 成为网管人员关心的问题。实时监测可以在最早的时间内发现问题,避免网络长 时间继线。本文介绍一种利用Delphi编写应用程序实现专线状态探测的方法。

实现原理

许多人经常利用Windows中的两条DOS命令(Ping和Tracert)来测试网络状态,其原理是通过向探测的节点端口发送数据包请求,然后从该端口是否应答来判断网络是否畅通。其实,在Windows的System目录下有一个Icmp.dll文件,该动态链接库提供了ICMP协议的所有功能,通过对该动态链接库的调用可以完成发送 请求和接收应答。因此,可以利用该动态链接库实现专线状态的探测。

Icmp.dll文件内的主要调用函数如下:

● IcmpCreateFile: 打开一个句柄,通过该句柄发送ICMP的请求报文;

● IcmpCloseHandle: 关闭通过IcmpCreateFile函数打开的句柄;

● IcmpSendEcho:通过打开的句柄发送ICMP请求,在超时或接收到应答报文 后返回。

编程实现

首先构造节点库(如图1所示),然后通过调用ICMP协议,向测试端口发送请 求,如果接收到该端口的应答,则状态为“正常”,否则,状态为“中断”。

1. 初始化WinSock,调入Icmp.dll库

var
  wsadata: TWSAData;
begin
  if WSAStartup($101,wsadata) <> 0 then begin
ShowMessage(‘Error initialising WinSock’);
   halt;
  end;
  hICMPlib ∶= loadlibrary(icmpDLL);
  if hICMPlib <> null then begin
   @ICMPCreateFile ∶= GetProcAddress(hICMPlib, ‘IcmpCreateFile’ );
   @IcmpCloseHandle∶= GetProcAddress(hICMPlib, ‘IcmpCloseHandle ’);
@IcmpSendEcho∶= GetProcAddress(hICMPlib,
‘IcmpSendEcho’);
if (@ICMPCreateFile = Nil) or (@IcmpCloseHandle = Nil) or (@IcmpSendEcho=Nil) then begin
ShowMessage(‘Error loading dll functions’);
halt;
   end;
   hICMP ∶= IcmpCreateFile;
  if hICMP=INVALID_HANDLE_VALUE then begin
ShowMessage(‘Unable to get ping handle’);
   halt;
   end;
  end;
  else begin
ShowMessage(‘Unable to register’+ icmpDLL);
halt;
  end;
end;

2. 使用定时器启动探测

在测试中,如果端口状态正常,则net_stat=0;状态异常则net_stat=1,并 显示“中断”,系统响铃报警。对节点表中所有节点进行测试的主要代码如下:

//取得欲测试端口的IP地址
net_ip∶=Table1. FieldByName(‘对端IP’). asstring;
//调用端口测试
Test(Sender);
if net_stat=0 then
  begin
  Table1. FieldByName(‘状态’). asstring∶=‘中断’;
//端口异常,则net=1
if net=0 then net∶=1;
  end
else Table1. FieldByName(‘状态’). asstring∶=‘正常’;
//整表测试后,如有异常的端口,则10次响铃报警
if net=1 then FOR I∶=1 TO 10 DO PlaySound(‘RINGIN’, 0, SND_RESOURCE);

3. 探测指定的端口:Test(Sender)

const
Size = 56;
TimeOut = 3000;
var
Address: DWord;
HostName, HostIP: String;
Phe: PHostEnt;
BufferSize, nPkts: Integer;
pReqData, pData: Pointer;
pIPE: PIcmpEchoReply;
IPOpt: TIPOptionInformation;
begin
//将存储字符串的地址转化为标准的网络IP地址
Address ∶= inet_addr(PChar(net_ip));
//取得测试端口的句柄
Phe ∶= GetHostByAddr(@Address, 4, PF_INET);
// 设定一个缓冲区,填充指定数据作为待发送的数据包
BufferSize ∶= SizeOf(TICMPEchoReply) + Size;
GetMem(pReqData, Size);
GetMem(pData, Size);
GetMem(pIPE, BufferSize);
FillChar(pReqData^, Size, $AA);
pIPE^.Data ∶= pData;
FillChar(IPOpt, SizeOf(IPOpt), 0);
IPOpt.TTL ∶= 64;
  //通过打开的句柄,发送ICMP数据包请求,在超时或接收应答报文后返回
NPkts ∶= IcmpSendEcho(hICMP, Address, pReqData, Size, @IPOpt, pIPE, BufferSize, TimeOut);
//根据是否从测试端口返回应答报文,判断网络状态
  if NPkts = 0 then net_stat∶=0
else begin
HostIP ∶= StrPas(inet_ntoa(TInAddr(pIPE^.Address)));
if trim(HostIP)=trim(net_ip) then net_stat∶=1
else net_stat∶=0;
end;
//释放变量
FreeMem(pIPE);
FreeMem(pData);
FreeMem
(pReqData);
end;
4. 关闭探测程序
//释放ICMP
IcmpCloseHandle(hICMP);
FreeLibrary(hICMPlib);
//释放WinSock
if WSACleanup <> 0 then ShowMessage(‘Error freeing WinSock’);

完善程序

上述程序仅提供了基本的网络探测方法,为了更好地体现网络状态和处理情 况,可以对此程序进一步完善:

1. 再建两个表:

● 故障记录和处理表: 在探测中将故障节点记录保存,并记录故障处理情况 ;

● 探测间隔表:灵活设置探测时间间隔。

2. 添加节点库维护模块。

3. 对于探测模块的显示进行改造,使故障节点呈现报警色(如红色)。

 

在线服务QQ:99923144 Delphi程序员QQ群(139442)
Delphi知识中心 www.delphi.ee 最专业的Delphi技术资料网站