bestlong 怕失憶論壇

 

 

搜索
bestlong 怕失憶論壇 論壇 Delphi 用 Delphi 實現網路專線狀態的探測
查看: 3542|回復: 0
go

用 Delphi 實現網路專線狀態的探測 [複製鏈接]

Rank: 9Rank: 9Rank: 9

1#
發表於 2006-6-23 14:21 |只看該作者 |倒序瀏覽 |打印
范智鑫 王毅燕

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

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

Icmp.dll文件内的主要调用函数如下:
● IcmpCreateFile: 打开一个句柄,通过该句柄发送ICMP的请求报文;
● IcmpCloseHandle: 关闭通过IcmpCreateFile函数打开的句柄;
● IcmpSendEcho:通过打开的句柄发送ICMP请求,在超时或接收到应答报文后返回。

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

图1
1. 初始化WinSock,调入Icmp.dll库
  1. var
  2.  wsadata: TWSAData;
  3. begin
  4.  if WSAStartup($101,wsadata) <> 0 then
  5.  begin
  6.     ShowMessage(‘Error initialising WinSock’);
  7.   halt;
  8.  end;
  9.  hICMPlib ∶= loadlibrary(icmpDLL);
  10.  if hICMPlib <> null then
  11.  begin
  12.   @ICMPCreateFile ∶= GetProcAddress(hICMPlib, ‘IcmpCreateFile’);
  13.   @IcmpCloseHandle∶= GetProcAddress(hICMPlib, ‘IcmpCloseHandle’);
  14.     @IcmpSendEcho∶= GetProcAddress(hICMPlib, IcmpSendEcho’);
  15.     if (@ICMPCreateFile = Nil) or (@IcmpCloseHandle = Nil) or (@IcmpSendEcho=Nil) then begin
  16.       ShowMessage(‘Error loading dll functions’);
  17.       halt;
  18.   end;
  19.   hICMP ∶= IcmpCreateFile;
  20.     if hICMP=INVALID_HANDLE_VALUE then
  21.     begin
  22.       ShowMessage(‘Unable to get ping handle’);
  23.     halt;
  24.   end;
  25.  end;
  26.  else begin
  27.   ShowMessage(‘Unable to register’+ icmpDLL);
  28. halt;
  29.  end;
  30. 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)
  1. const
  2.   Size = 56;
  3.   TimeOut = 3000;
  4. var
  5.   Address: DWord;
  6.   HostName, HostIP: String;
  7.   Phe: PHostEnt;
  8.   BufferSize, nPkts: Integer;
  9.   pReqData, pData: Pointer;
  10.   pIPE: PIcmpEchoReply;
  11.   IPOpt: TIPOptionInformation;
  12. begin
  13.   //将存储字符串的地址转化为标准的网络IP地址
  14.   Address := inet_addr(PChar(net_ip));
  15.   //取得测试端口的句柄
  16.   Phe := GetHostByAddr(@Address, 4, PF_INET);
  17.   // 设定一个缓冲区,填充指定数据作为待发送的数据包
  18.   BufferSize := SizeOf(TICMPEchoReply) + Size;
  19.   GetMem(pReqData, Size);
  20.   GetMem(pData, Size);
  21.   GetMem(pIPE, BufferSize);
  22.   FillChar(pReqData^, Size, $AA);
  23.   pIPE^.Data := pData;
  24.   FillChar(IPOpt, SizeOf(IPOpt), 0);
  25.   IPOpt.TTL := 64;
  26.  //通过打开的句柄,发送ICMP数据包请求,在超时或接收应答报文后返回
  27.   NPkts := IcmpSendEcho(hICMP, Address, pReqData, Size, @IPOpt, pIPE, BufferSize, TimeOut);
  28.   //根据是否从测试端口返回应答报文,判断网络状态
  29.  if NPkts = 0 then net_stat := 0
  30.   else begin
  31.     HostIP := StrPas(inet_ntoa(TInAddr(pIPE^.Address)));
  32.     if trim(HostIP) = trim(net_ip) then
  33.       net_stat := 1
  34.     else
  35.       net_stat := 0;
  36.   end;
  37.   //释放变量
  38.   FreeMem(pIPE);
  39.   FreeMem(pData);
  40.   FreeMem(pReqData);
  41. end;
複製代碼


4. 关闭探测程序
//释放ICMP
IcmpCloseHandle(hICMP);
FreeLibrary(hICMPlib);

//释放WinSock
if WSACleanup <> 0 then ShowMessage(‘Error freeing WinSock’);

完善程序
上述程序仅提供了基本的网络探测方法,为了更好地体现网络状态和处理情况,可以对此程序进一步完善:
1. 再建两个表:
● 故障记录和处理表: 在探测中将故障节点记录保存,并记录故障处理情况;
● 探测间隔表:灵活设置探测时间间隔。
2. 添加节点库维护模块。
3. 对于探测模块的显示进行改造,使故障节点呈现报警色(如红色)。
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw
‹ 上一主題|下一主題

Archiver|怕失憶論壇

GMT+8, 2024-4-30 19:18 , Processed in 0.010973 second(s), 10 queries .

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.