请教大家一个局域网连接问题?如何判断我机器是否与局域网中指定服务器连接呢?我用SCOCKET判断可以但很慢,请教有没有好的办法啊!多谢,在线等!

解决方案 »

  1.   

    用ping命令
    首先,对编程中需要的动态链接库作一简要说明:在Windows的System目录下,你可以找到Icmp.dll文件,该动态链接库提供了ICMP协议的所有功能,我们的编程就建立在对该动态链接库的调用上。 
      Icmp.dll文件内的调用函数说明如下: 
      1、IcmpCreateFile 
      打开一个句柄,通过该句柄你可以发送ICMP的请求回送报文。 
      2、IcmpCloseHandle 
      关闭你通过IcmpCreateFile函数打开的句柄。 
      3、IcmpSendEcho 
      通过你打开的句柄发送ICMP请求,在超时或应答报文接收后返回。其参数基本上和它的帧结构一致,可参下面的程序部分,其具体含意你可以参看有关ICMP协议的书籍。 
      初步了解了上述的三个函数后,我们就可以开始编程了。 
      首先,我们的程序运行后应该有如图1所示的基本功能。例程运行示意图 
      然后,在程序的开始部分(FormCreate)对WinSocket进行初始化,其作用是申明使用的版本信息,同时调入Icmp.dll库。 
      type 
       PIPOptionInformation = ^TIPOptionInformation; 
       TIPOptionInformation = packed record 
       TTL: Byte; 
       TOS: Byte; 
       Flags: Byte; 
       OptionsSize: Byte; 
       OptionsData: PChar; 
       end; 
       PIcmpEchoReply = ^TIcmpEchoReply; 
       TIcmpEchoReply = packed record 
       Address: DWORD; 
       Status: DWORD; 
       RTT: DWORD; 
       DataSize: Word; 
       Reserved: Word; 
       Data: Pointer; 
       Options: TIPOptionInformation; 
       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; 
       TMyPing = class(TForm) 
       Panel1: TPanel; 
       Label1: TLabel; 
       PingEdit: TEdit; 
       ExeBtn: TButton; 
       Button2: TButton; 
       Button3: TButton; 
       StatusShow: TMemo; 
       procedure Button3Click(Sender: TObject); 
       procedure FormCreate(Sender: TObject); 
       procedure ExeBtnClick(Sender: TObject); 
       private 
       { Private declarations } 
       hICMP: THANDLE; 
       IcmpCreateFile : TIcmpCreateFile; 
       IcmpCloseHandle: TIcmpCloseHandle; 
       IcmpSendEcho: TIcmpSendEcho; 
       public 
       { Public declarations } 
      end; 
      procedure TMyPing.FormCreate(Sender: TObject); 
      var 
       WSAData: TWSAData; 
       hICMPdll: HMODULE; 
      begin 
       WSAStartup($101, WSAData); 
       // Load the icmp.dll stuff 
       hICMPdll := LoadLibrary('icmp.dll'); 
       @ICMPCreateFile := GetProcAddress(hICMPdll, 'IcmpCreateFile'); 
       @IcmpCloseHandle := GetProcAddress(hICMPdll, 'IcmpCloseHandle'); 
       @IcmpSendEcho := GetProcAddress(hICMPdll, 'IcmpSendEcho'); 
       hICMP := IcmpCreateFile; 
       StatusShow.Text := ''; 
       StatusShow.Lines.Add('目的IP地址 字节数 返回时间(毫秒)'); 
      end; 
      接下来,就要进行如下所示的Ping操作的实际编程过程了。 
      procedure TMyPing.ExeBtnClick(Sender: TObject); 
      var 
       IPOpt:TIPOptionInformation;// IP Options for packet to send 
       FIPAddress:DWORD; 
       pReqData,pRevData:PChar; 
       pIPE:PIcmpEchoReply;// ICMP Echo reply buffer 
       FSize: DWORD; 
       MyString:string; 
       FTimeOut:DWORD; 
       BufferSize:DWORD; 
      begin 
       if PingEdit.Text < >  '' then 
       begin 
       FIPAddress := inet_addr(PChar(PingEdit.Text)); 
       FSize := 40; 
       BufferSize := SizeOf(TICMPEchoReply) + FSize; 
       GetMem(pRevData,FSize); 
       GetMem(pIPE,BufferSize); 
       FillChar(pIPE^, SizeOf(pIPE^), 0); 
       pIPE^.Data := pRevData; 
       MyString := 'Hello,World'; 
       pReqData := PChar(MyString); 
       FillChar(IPOpt, Sizeof(IPOpt), 0); 
       IPOpt.TTL := 64; 
       FTimeOut := 4000; 
       IcmpSendEcho(hICMP, FIPAddress, pReqData, Length(MyString), @IPOpt, pIPE, BufferSize, FTimeOut);    if pReqData^ = pIPE^.Options.OptionsData^ then    begin    StatusShow.Lines.Add(PChar(PingEdit.Text) + ' ' +IntToStr(pIPE^.DataSize) + ' ' +IntToStr(pIPE^.RTT));    end;    FreeMem(pRevData);    FreeMem(pIPE);    end   end;