如何通过DELPHI编程的方式确认局域网里的一个IP是否已经连接网络

解决方案 »

  1.   

    用PING的方法会被防火墙给挡住,无法真实的反应情况,除了PING之外还有其他方法吗
      

  2.   

    只要你用网络发包,就有可能被防火墙挡住。所以即使有除了ping之外的其他方法,也满足不了你的要求~!
      

  3.   

    那像网络执法管那样的软件就能在防火墙开启的情况下,依然可以探测到主机的网络状态
    ---------------------我没有用过网络执法官这样的软件, 但, 估计, 它是要在每台机器上安装一个Server端或Client端的. 也就是说, 给防火墙开了后门.
      

  4.   

    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls,Registry,WinInet;type
      TForm1 = class(TForm)
        Timer1: TTimer;
        Button1: TButton;
        Button2: TButton;
        Button3: TButton;
        Edit1: TEdit;
        Memo1: TMemo;
        procedure Button2Click(Sender: TObject);
        procedure Button1Click(Sender: TObject);
        procedure Button3Click(Sender: TObject);
        procedure Timer1Timer(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
    implementation{$R *.dfm}
    function CheckOffline: boolean;
    var
      ConnectState: DWORD;
      StateSize: DWORD;
    begin
      ConnectState:= 0;
      StateSize:= SizeOf(ConnectState);
      result:= false;
      if InternetQueryOption(nil, INTERNET_OPTION_CONNECTED_STATE, @ConnectState, StateSize) then
      if (ConnectState and INTERNET_STATE_DISCONNECTED) <> 2 then result:= true;
    end;procedure TForm1.Button2Click(Sender: TObject);
    var
     b: array[0..4] of Byte;
    begin
      with TRegistry.Create do
            try
               RootKey := HKEY_LOCAL_MACHINE;
               OpenKey('System\CurrentControlSet\Services\RemoteAccess',False);
               ReadBinaryData('Remote Connection',b,4);
            finally
               Free;
            end;
     if b[0]=1 then Caption:='在线' else Caption:='离线';
    end;
    procedure TForm1.Button1Click(Sender: TObject);
    begin
     if InternetCheckConnection('http://mail.163.com/', 1, 0) then Caption:= 'Connected'   else  Caption:= 'Disconnected';
    end;procedure TForm1.Button3Click(Sender: TObject);
    begin
      if CheckOffline then  Caption:='在线' else Caption:='离线';
    end;end.
      

  5.   

    我收集了个公共函数,贴上来,需要添加winsock单元引用(也是逃不过防火墙)
    Function CheckNet(IpAddr: string): Boolean;
    type
      PIPOptionInformation = ^TIPOptionInformation;
      TIPOptionInformation = packed record
         TTL:         Byte;      // Time To Live (used for traceroute)
         TOS:         Byte;      // Type Of Service (usually 0)
         Flags:       Byte;      // IP header flags (usually 0)
         OptionsSize: Byte;      // Size of options data (usually 0, max 40)
         OptionsData: PChar;     // Options data buffer
      end;  PIcmpEchoReply = ^TIcmpEchoReply;
      TIcmpEchoReply = packed record
         Address:       DWord;                // replying address
         Status:        DWord;                // IP status value (see below)
         RTT:           DWord;                // Round Trip Time in milliseconds
         DataSize:      Word;                 // reply data size
         Reserved:      Word;
         Data:          Pointer;              // pointer to reply data buffer
         Options:       TIPOptionInformation; // reply options
      end;  TIcmpCreateFile = function: THandle; stdcall;
      TIcmpCloseHandle = function(IcmpHandle: THandle): Boolean; stdcall;
      TIcmpSendEcho = function(
         IcmpHandle:          THandle;
         DestinationAddress:  DWord;
         RequestData:         Pointer;
         RequestSize:         Word;
         RequestOptions:      PIPOptionInformation;
         ReplyBuffer:         Pointer;
         ReplySize:           DWord;
         Timeout:             DWord
      ): DWord; stdcall;const
      Size = 32;
      TimeOut = 1000;
    var
      wsadata: TWSAData;
      Address: DWord;                     // Address of host to contact
      HostName, HostIP: String;           // Name and dotted IP of host to contact
      Phe: PHostEnt;                      // HostEntry buffer for name lookup
      BufferSize, nPkts: Integer;
      pReqData, pData: Pointer;
      pIPE: PIcmpEchoReply;               // ICMP Echo reply buffer
      IPOpt: TIPOptionInformation;        // IP Options for packet to send
    const
      IcmpDLL = 'icmp.dll';
    var
      hICMPlib: HModule;
      IcmpCreateFile : TIcmpCreateFile;
      IcmpCloseHandle: TIcmpCloseHandle;
      IcmpSendEcho:    TIcmpSendEcho;
      hICMP: THandle;                     // Handle for the ICMP Calls
    begin
      // initialise winsock
      Result:=True;
      if WSAStartup(2,wsadata) <> 0 then begin
         Result:=False;
         halt;
      end;
      // register the icmp.dll stuff
      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
            Result:=False;
            halt;
        end;
        hICMP := IcmpCreateFile;
        if hICMP = INVALID_HANDLE_VALUE then begin
          Result:=False;
          halt;
        end;
      end else begin
        Result:=False;
        halt;
      end;
    // ------------------------------------------------------------
      Address := inet_addr(PChar(IpAddr));
      if (Address = INADDR_NONE) then begin
        Phe := GetHostByName(PChar(IpAddr));
        if Phe = Nil then Result:=False
        else begin
          Address := longint(plongint(Phe^.h_addr_list^)^);
          HostName := Phe^.h_name;
          HostIP := StrPas(inet_ntoa(TInAddr(Address)));
        end;
      end
      else begin
        Phe := GetHostByAddr(@Address, 4, PF_INET);
        if Phe = Nil then Result:=False;
      end;  if Address = INADDR_NONE then
      begin
         Result:=False;
      end;
      // Get some data buffer space and put something in the packet to send
      BufferSize := SizeOf(TICMPEchoReply) + Size;
      GetMem(pReqData, Size);
      GetMem(pData, Size);
      GetMem(pIPE, BufferSize);
      FillChar(pReqData^, Size, $AA);
      pIPE^.Data := pData;    // Finally Send the packet
      FillChar(IPOpt, SizeOf(IPOpt), 0);
      IPOpt.TTL := 64;
      NPkts := IcmpSendEcho(hICMP, Address, pReqData, Size,
                            @IPOpt, pIPE, BufferSize, TimeOut);
      if NPkts = 0 then Result:=False;  // Free those buffers
      FreeMem(pIPE); FreeMem(pData); FreeMem(pReqData);// --------------------------------------------------------------
      IcmpCloseHandle(hICMP);
      FreeLibrary(hICMPlib);
      // free winsock
      if WSACleanup <> 0 then Result:=False;
    end;
      

  6.   

    网络执法官用了winpcap包开发,基于ARP层,还没上升到IP层,所以可以看见所有网内的机器,不在一个网段也能看见,IP不行,用iphlpapl.dll中的SendArp,有响应就是开着机器,没有就是没联网
    网上有代码
      

  7.   

    使用Indy Clients 下的 IdIcmpClient 组件应该可以满足你的要求:procedure   TForm1.FormCreate(Sender:   TObject);  
      begin  
        try  
          idicmpclient1.Host:='192.xxx.xxx.xxx';//對方機子  
          IdIcmpClient1.Ping();  
          if     IdIcmpClient1.ReplyStatus.FromIpAddress='192.xxx.xxx.xxx'   then  
          begin  
            ShowMessage('網絡通') 
          end  
          else  
          ShowMessage('網絡不通')  
        except  
          ShowMessage('網絡不通')  
        end;  
      end;