www.pudn.com > netcheck.zip > netCheck.pas


unit netCheck; 
 
interface 
 
uses 
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, 
  Db, DBTables, Grids, DBGrids, Menus, ComCtrls,WinSock, ExtCtrls; 
 
const 
  NetCheck_Time=5;                  //自动监测的时间间隔(分钟) 
type 
  TNetCheckForm = class(TForm) 
    NetChech_Menu: TMainMenu; 
    StartupItem: TMenuItem; 
    HandNetCheckItem: TMenuItem; 
    N1: TMenuItem; 
    ExitItem: TMenuItem; 
    LibModifyItem: TMenuItem; 
    ModifyItem: TMenuItem; 
    N2: TMenuItem; 
    AppendItem: TMenuItem; 
    N3: TMenuItem; 
    InsertItem: TMenuItem; 
    N4: TMenuItem; 
    DeleteItem: TMenuItem; 
    SystemItem: TMenuItem; 
    NetLibDBGrid: TDBGrid; 
    NetLibDataSource: TDataSource; 
    NetLibTable: TTable; 
    NetCheckStatusBar: TStatusBar; 
    LogItem: TMenuItem; 
    N5: TMenuItem; 
    AboutItem: TMenuItem; 
    DbCreateQuery: TQuery; 
    CreateLibItem: TMenuItem; 
    N6: TMenuItem; 
    NetCheck_Timer: TTimer; 
    N7: TMenuItem; 
    AutoNetcheckItem: TMenuItem; 
    procedure ModifyItemClick(Sender: TObject); 
    procedure AppendItemClick(Sender: TObject); 
    procedure InsertItemClick(Sender: TObject); 
    procedure DeleteItemClick(Sender: TObject); 
    procedure ExitItemClick(Sender: TObject); 
    procedure HandNetCheckItemClick(Sender: TObject); 
    procedure Net_Check(Sender:TObject); 
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean); 
    procedure NetLibDBGridDrawColumnCell(Sender: TObject; 
      const Rect: TRect; DataCol: Integer; Column: TColumn; 
      State: TGridDrawState); 
    procedure FormActivate(Sender: TObject); 
    procedure AboutItemClick(Sender: TObject); 
    procedure LogItemClick(Sender: TObject); 
    procedure CreateLibItemClick(Sender: TObject); 
    procedure ReCreateLib(Sender: TObject); 
    procedure AutoNetcheckItemClick(Sender: TObject); 
  private 
    { Private declarations } 
  public 
    { Public declarations } 
  end; 
 
//ICMP应用程序接口中相关的数据结构 
TIP_Option_Information = record 
  TTL:Byte;                 //存活时间(用于路由跟踪) 
  TOS:Byte;                 //服务类型(通常为0) 
  Flags:Byte;               //IP头标志(通常为0) 
  OptionsSize:Byte;         //附加数据大小 
  OptionsData:PChar;        //附加数据 
  end; 
 
TIcmp_Echo_Reply = packed record 
  Address:DWord;             //应答的主机地址 
  Status:DWord;              //IP状态码 
  RTT:DWord;                 //往返应答时间(以毫秒计) 
  DataSize:Word;             //回波应答数据大小(以字节计) 
  Reserved:Word;             //系统保留 
  Data:Pointer;              //回波应答数据指针 
  Options: TIP_Option_Information;  // 
  end; 
 
PIP_Option_Information=^TIP_Option_Information; 
PIcmp_Echo_Reply=^TIcmp_Echo_Reply; 
 
//相关函数声明 
Function IcmpCreateFile:THandle;stdcall; external 'ICMP.DLL'; 
Function IcmpCloseHandle(Icmphandle:THandle):Boolean; stdcall; external 'ICMP.DLL'; 
Function IcmpSendEcho( 
         IcmpHandle:THandle;       //用于IcmpCreateFile 打开的ICMP句柄 
         DestinationAddress:DWord; //目标主机地址 
         RequestData:Pointer;      //回波请求所发数据的缓冲区 
         RequestSize:Word;         //回波请求数据的缓冲区大小(以字节计) 
         RequestOption:PIP_Option_InFormation;  //回波请求中IP报头选项地址,可以为空 
         ReplyBuffer:Pointer;      //用于存储回波应答数据的缓冲区 
         ReplySize:DWord;          //回波应答数据的缓冲区大小(以字节计) 
         TimeOut:DWord             //等待回应的时间(以毫秒计) 
         ):DWord; stdcall; external 'ICMP.DLL'; 
 
Function YearMonthString:String; 
procedure CreateNSLog(S:String); 
 
var 
  NetCheckForm: TNetCheckForm; 
 
implementation 
 
Uses About, Historylog; 
{$R *.DFM} 
 
Function YearMonthString;  //产生年月份串,供产生记录文件用 
var 
  Present:TDateTime; 
  Year, Month,Day:Word; 
 begin 
  Present:=Now; 
  DecodeDate(Present, Year,Month, Day); 
  if Month > 9 then 
    Result:=IntToStr(Year)+IntToStr(Month) 
    else 
      Result:=IntToStr(Year)+'0'+IntToStr(Month); 
end; 
 
procedure CreateNSLog(S:String); 
var 
  NSLog:String; 
  TFile:TextFile; 
begin 
  NSLog:='NS'+ YearMonthString + '.LOG'; 
  if FileExists(NSLog) then 
     begin 
      AssignFile(TFile,NSLog); 
      Append(TFile); 
     end 
      else 
         begin 
         AssignFile(TFile,NSLog); 
         Rewrite(TFile); 
         end; 
  Writeln(TFile,S); 
  CloseFile(TFile); 
end; 
 
procedure TNetCheckForm.ReCreateLib(Sender: TObject); 
begin 
  Screen.Cursor:=CrHourglass; 
  try 
   With DbCreateQuery do 
     begin 
     Close; 
     SQL.Clear; 
     SQL.Add('CREATE TABLE "IPLIB.DB"'); 
     SQL.Add('(对端名称 CHAR(30),对端IP CHAR(15),状态 CHAR(8),联系电话 CHAR(18))'); 
     Active := True; 
     Close; 
     end; 
  except 
    on ENoResultSet do ; 
    else 
    MessageBox(0,'重建库结构失败,请重试!','提示',MB_ICONEXCLAMATION ) 
  end; 
  Screen.Cursor:=CrDefault; 
end; 
 
procedure TNetCheckForm.Net_Check(Sender:TObject); 
Const 
 PacketSize =32; 
 TimeOut = 5000; 
Var 
  ICMPHandle:Thandle; 
  DestAddress:DWord;                       //目标主机IP地址 
  RequestDataBuffer:Pointer;               //请求数据缓冲区指针 
  ReplyDataBuffer:Pointer;                 //应答数据缓冲区指针 
  IPOptionInfo:TIP_Option_Information;     //待发送数据包的IP选项 
  ICMPEchoReplyBuffer:PIcmp_Echo_Reply;    //ICMP回波应答缓冲区 
  Echo_Result:Integer;                      //ICMPSendEcho函数返回值 
  TIPAddress,NameString:String; 
begin 
  ICMPHandle:=IcmpCreateFile;                //打开ICMP句柄 
  if ICMPHandle = INVALID_HANDLE_VALUE then 
    begin 
     MessageBox(0,'得到ICMP句柄错误','错误',MB_ICONEXCLAMATION); 
     Exit; 
    end; 
 
  GetMem(RequestDataBuffer,PacketSize);       //分配请求数据缓冲区 
  FillChar(RequestDataBuffer^,PacketSize,$FF);//填充请求数据缓冲区 
 
  FillChar(IPOptionInfo,Sizeof(IPOptionInfo),0);  //填充IP选项数据 
  IPOptionInfo.TTL:=64;                           //设置存活期 
 
  GetMem(ReplyDataBuffer,PacketSize);             //分配应答数据缓冲区 
  GetMem(ICMPEchoReplyBuffer,SizeOf(TIcmp_Echo_Reply)+PacketSize);  //分配回波应答结构缓冲区 
  ICMPEchoReplyBuffer^.Data:=ReplyDataBuffer;     //填入缓冲区指针 
 
  NetLibDataSource.DataSet.First; 
  NetlibDataSource.DataSet.Edit; 
  while not NetLibDataSource.DataSet.EOF do 
   begin 
     TIpAddress:=NetLibDataSource.DataSet.FieldByName('对端IP').AsString;       //从IP库中取对端IP地址 
     NameString:=NetLibDataSource.DataSet.FieldByName('对端名称').AsString;     //从IP库中取对端名称 
 
     DestAddress:=Inet_addr(PChar(TIpAddress));  //将目标地址转换成网络格式 
     Echo_Result:=IcmpSendEcho(ICMPHandle,DestAddress,RequestDataBuffer,PacketSize,@IPOptionInfo,ICMPEchoReplyBuffer, 
                 Sizeof(TIcmp_Echo_Reply)+PacketSize,TimeOut);     //发送回波请求,并等待回波应答 
 
     if Echo_Result <> 0 then      //判断回波并给出网络结果 
        begin 
        NetLibDataSource.DataSet.FieldByName('状态').AsString:='正常'; 
        CreateNSLog(DateTimeToStr(Now)+'  '+ NameString+':['+TIpAddress+']   连接正常'); 
        end 
       else 
         begin 
         NetLibDataSource.DataSet.FieldByName('状态').AsString:='中断'; 
         CreateNSLog(DateTimeToStr(Now)+'  '+ NameString+':['+TIpAddress+']   连接中断'); 
         end; 
     NetLibDataSource.DataSet.Next; 
     NetlibDataSource.DataSet.Edit; 
   end; 
 
  Freemem(ICMPEchoReplyBuffer);  //释放分配的内存空间 
  Freemem(ReplyDataBuffer); 
  FreeMem(RequestDataBuffer); 
  IcmpCloseHandle(ICMPHandle);   //关闭ICMP句柄 
 
  NetCheckStatusBar.Panels[1].Text:=DateTimeToStr(Now); 
end; 
 
procedure TNetCheckForm.FormActivate(Sender: TObject); 
Var 
 WSAdata:TWSAData;                         //Winsock数据结构 
begin 
  if WSAStartup($102,WSAdata) <> 0 then 
   begin 
   MessageBox(0,'初始化WINSOCK错误','初始化提示',MB_ICONEXCLAMATION); 
   Halt; 
   end; 
 
  if FileExists(ExtractFilePath(Application.ExeName)+'IPLib.db') then 
     try 
      CreateLibItem.Enabled:=False; 
      NetLibTable.DatabaseName := ExtractFilePath(Application.ExeName); 
      NetLibTable.TableName := 'IPLib.db'; 
      NetLibTable.Open; 
      HandNetCheckItem.Checked :=True; 
      except 
      MessageBox(0,'数据库[IPLIB.DB]错误,请删除并重建!','错误', MB_ICONEXCLAMATION); 
      LibModifyItem.Enabled:=False; 
      HandNetCheckItem.Enabled:=False; 
      AutoNetCheckItem.Enabled:=False; 
     end 
   else 
     begin 
      MessageBox(0,'数据库[IPLIB.DB]不存在,请重建!','错误', MB_ICONEXCLAMATION); 
      LibModifyItem.Enabled:=False; 
      HandNetCheckItem.Enabled:=False; 
      AutoNetCheckItem.Enabled:=False; 
      CreateLibItem.Enabled:=True; 
     end; 
end; 
 
procedure TNetCheckForm.ModifyItemClick(Sender: TObject); 
begin 
   NetLibDBGrid.ReadOnly:=False; 
   NetLibDataSource.DataSet.Edit; 
end; 
 
procedure TNetCheckForm.AppendItemClick(Sender: TObject); 
begin 
   NetLibDBGrid.ReadOnly:=False; 
   NetLibDataSource.DataSet.Append; 
end; 
 
procedure TNetCheckForm.InsertItemClick(Sender: TObject); 
begin 
   NetlibDBGrid.ReadOnly:=False; 
   NetlibDataSource.DataSet.Insert; 
end; 
 
procedure TNetCheckForm.DeleteItemClick(Sender: TObject); 
Var 
  MessageString:String; 
begin 
  MessageString:=NetLibDataSource.DataSet.FieldByName('对端名称').AsString; 
  if MessageBox(0,PChar('您要删除所选IP记录['+MessageString+']吗?'),'删除提示',MB_YESNO or MB_ICONEXCLAMATION )= IDYES then 
     NetLibDataSource.DataSet.Delete 
     else 
       Exit; 
end; 
 
procedure TNetCheckForm.ExitItemClick(Sender: TObject); 
begin 
 Application.Terminate; 
end; 
 
procedure TNetCheckForm.HandNetCheckItemClick(Sender: TObject); 
begin 
 NetCheck_Timer.Enabled :=False; 
 
 HandNetCheckItem.Checked :=True; 
 
 Net_Check(Self); 
end; 
 
procedure TNetCheckForm.AutoNetcheckItemClick(Sender: TObject); 
begin 
 AutoNetCheckItem.Checked :=True; 
 
 NetCheck_Timer.Interval :=NetCheck_Time*60*1000; 
 
 NetCheck_Timer.Enabled :=True; 
end; 
 
 
procedure TNetCheckForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean); 
begin 
  NetLibDataSource.DataSet.Close; 
  if WSACleanup <> 0 then 
       MessageBox(0,'无法关闭WINSOCK','错误',MB_ICONEXCLAMATION); 
end; 
 
procedure TNetCheckForm.NetLibDBGridDrawColumnCell(Sender: TObject; 
  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); 
begin 
  if NetLibDataSource.DataSet.FieldByName('状态').AsString='中断' then 
    begin 
     NetlibDBGrid.Canvas.Font.Color:=clRed; 
     NetLibDbGrid.DefaultDrawColumnCell(Rect,DataCol,Column,State); 
     NetLibDBGrid.Canvas.Font.Color:=clBlack; 
    end; 
end; 
 
procedure TNetCheckForm.CreateLibItemClick(Sender: TObject); 
begin 
   ReCreateLib(Self) 
end; 
 
procedure TNetCheckForm.AboutItemClick(Sender: TObject); 
begin 
  AboutBox.ShowModal; 
end; 
 
procedure TNetCheckForm.LogItemClick(Sender: TObject); 
begin 
  LogForm.ShowModal; 
end; 
 
 
end.