Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用Delphi5快速检查网络位置是否存在?_Delphi_Networking_File Io - Fatal编程技术网

如何使用Delphi5快速检查网络位置是否存在?

如何使用Delphi5快速检查网络位置是否存在?,delphi,networking,file-io,Delphi,Networking,File Io,可能的重复项: 我们需要将文本写入网络上的文件,但可能存在这样的情况:该位置不存在,我们需要将文本写入另一个位置。如何快速检查网络位置是否存在?尝试使用“try…except”将文本写入不存在的位置需要30秒(ish)。肯定有更快的办法吧 如果有人能给我一些建议,我将不胜感激 谢谢 使用。在Delphi5中,FileExists是内置的(在SysUtils库中) 我不确定是否有任何方法可以“快速”做到这一点。如果您注意到windows通过Samba解析不存在的网络位置所需的时间,则大约需要3

可能的重复项:

我们需要将文本写入网络上的文件,但可能存在这样的情况:该位置不存在,我们需要将文本写入另一个位置。如何快速检查网络位置是否存在?尝试使用“try…except”将文本写入不存在的位置需要30秒(ish)。肯定有更快的办法吧

如果有人能给我一些建议,我将不胜感激

谢谢

使用。在Delphi5中,FileExists是内置的(在SysUtils库中)


我不确定是否有任何方法可以“快速”做到这一点。如果您注意到windows通过Samba解析不存在的网络位置所需的时间,则大约需要30秒。这可能与samba调用的windows API的内部超时有关(只是猜测)。

对于那些对Delphi上下文的答案感兴趣的人,我使用Indy组件IdIcmpClient组件ping IP,如下所示:

  IdIcmpClient1.Host:= '10.0.0.999';
  try
    IdIcmpClient1.Ping();
  except
    showmessage('Not found');
  end;
如果它不在那里,您只需3秒钟就可以得到结果,如果它在那里,您几乎可以立即得到结果。

I ping the location:

用法

bPingSuccess:=Ping(szServer,5000)

unituping;
接口
使用
窗户,
SysUtils,
班级;
类型
TSunB=压缩记录
s_b1、s_b2、s_b3、s_b4:字节;
结束;
压缩记录
s_w1,s_w2:单词;
结束;
PIPAddr=^TIPAddr;
TIPAddr=记录
大小写整数
0:(S_un_b:TSunB);;
1:(S_un_w:TSunW);;
2:(S_地址:长字);
结束;
IPAddr=TIPAddr;
TIcmpCreateFile=function():THandle;stdcall;
TIcmpCloseHandle=函数(icmpHandle:THandle):布尔值;stdcall;
TIcmpSendEcho=函数(IcmpHandle:THandle;DestinationAddress:IPAddr;RequestData:
指针;RequestSize:smallint;RequestOptions:Pointer;ReplyBuffer:Pointer;
回复:DWORD;超时:DWORD):DWORD;stdcall;
常数
IcmpCreateFile:TIcmpCreateFile=nil;
IcmpCloseHandle:TIcmpCloseHandle=nil;
IcmpSendEcho:TIcmpSendEcho=nil;
函数Ping(InetAddress:string;iTimeout:cardinal):布尔;
实施
使用
温索克;
函数Fetch(var AInput:string;const ADelim:string='';
const ADelete:boolean=True):字符串;
变量
iPos:整数;
开始
如果ADelim=#0,则
开始
//AnsiPos不适用于#0
首次公开募股:=Pos(ADelim,AInput);
结束
其他的
开始
首次公开募股:=Pos(ADelim,AInput);
结束;
如果iPos=0,则
开始
结果:=AInput;
如果是删除的话
开始
输入:='';
结束;
结束
其他的
开始
结果:=拷贝(输入,1,iPos-1);
如果是删除的话
开始
删除(AInput,1,IPO+长度(ADelim)-1);
结束;
结束;
结束;
过程translatestringtotinadr(AIP:string;var-AInAddr);
变量
phe:光能;
pac:PChar;
GInitData:TWSAData;
开始
WSAStartup(101美元,GInitData);
尝试
phe:=GetHostByName(PChar(AIP));
如果分配(phe),则
开始
pac:=phe^.h地址列表^;
如果分配(pac),则
开始
与TIPAddr(AInAddr)。S_un_b do
开始
s_b1:=字节(pac[0]);
s_b2:=字节(pac[1]);
s_b3:=字节(pac[2]);
s_b4:=字节(pac[3]);
结束;
结束
其他的
开始
引发异常。创建('从主机名获取IP时出错');
结束;
结束
其他的
开始
引发异常。创建('获取主机名时出错');
结束;
除了
FillChar(AInAddr,SizeOf(AInAddr),#0);
结束;
WSACleanup;
结束;
函数Ping(InetAddress:string;iTimeout:cardinal):布尔;
变量
hIcmpDll:HMODULE;
hIcmpFile:THandle;
InAddr:IPAddr;
DW:DWORD;
rep:byte的数组[1..128];
开始
结果:=假;
{加载库}
hIcmpDll:=LoadLibrary('icmp.dll');
如果(hIcmpDll=0),则
开始
引发异常。创建('icmp.dll库无法加载或找不到。'+
SysErrorMessage(GetLastError));
结束;
尝试
{加载所需过程的地址}
@IcmpCreateFile:=GetProcAddress(hIcmpDll,'IcmpCreateFile');
@IcmpSendEcho:=GetProcAddress(hIcmpDll,'IcmpSendEcho');
@IcmpCloseHandle:=GetProcAddress(hIcmpDll,'IcmpCloseHandle');
{如果在dll中找到过程}
如果已分配(IcmpCreateFile)、已分配(IcmpSendEcho)和已分配(IcmpCloseHandle)
然后
开始
hIcmpFile:=IcmpCreateFile;
尝试
如果hIcmpFile=无效的\u句柄\u值,则
出口
TranslateStringToIndaDR(InetAddress,IndaDR);
DW:=IcmpSendEcho(hIcmpFile,InAddr,nil,0,nil,@rep,128,iTimeout)//0);
结果:=(DW 0);
最后
IcmpCloseHandle(hIcmpFile);
结束;
结束;
最后
{卸载库}
免费图书馆(hIcmpDll);
结束;
结束;
结束。

谢谢,但我已经在使用它了。如果在网络上找不到我要访问的IP地址,仍然需要30秒来检查…这正是我所担心的-感谢您的回复。我会等一会儿,看看有没有其他人有什么想法。复制或,或感谢你为我指出了正确的方向-我看的时候找不到这些。我将尝试使用Ping技术…除了-它的响应速度更快。请注意,如果ICMP在您和目标之间的某个位置被阻止,这可能会提供无效信息。您是否在内部网络中使用超大字节作为地址?;-)Mick的回答引用了Embarcadero论坛上的一条消息,称Indy Icmp组件使用原始套接字,因此它只允许管理员使用。如果这对您有效,那么Indy已经改变了它的实现,或者您只是作为管理员进行测试。这是个坏主意,James。谢谢你提供的信息,但它不会有问题,因为它将运行的机器将始终由管理员用户登录-这是一个旧的遗留系统,只会继续运行!我意识到
unit uPing;

interface

uses
  Windows,
  SysUtils,
  Classes;

type
  TSunB = packed record
    s_b1, s_b2, s_b3, s_b4: byte;
  end;

  TSunW = packed record
    s_w1, s_w2: word;
  end;

  PIPAddr = ^TIPAddr;
  TIPAddr = record
    case integer of
      0: (S_un_b: TSunB);
      1: (S_un_w: TSunW);
      2: (S_addr: longword);
  end;

  IPAddr = TIPAddr;

  TIcmpCreateFile = function(): THandle; stdcall;
  TIcmpCloseHandle = function(icmpHandle: THandle): boolean; stdcall;
  TIcmpSendEcho = function(IcmpHandle: THandle; DestinationAddress: IPAddr; RequestData:
    Pointer; RequestSize: smallint; RequestOptions: pointer; ReplyBuffer: Pointer;
    ReplySize: DWORD; Timeout: DWORD): DWORD; stdcall;

const
  IcmpCreateFile: TIcmpCreateFile = nil;
  IcmpCloseHandle: TIcmpCloseHandle = nil;
  IcmpSendEcho: TIcmpSendEcho = nil;

function Ping(InetAddress: string; iTimeout: cardinal): boolean;

implementation

uses
  WinSock;

function Fetch(var AInput: string; const ADelim: string = ' ';
  const ADelete: boolean = True): string;
var
  iPos: integer;
begin
  if ADelim = #0 then
  begin
    // AnsiPos does not work with #0
    iPos := Pos(ADelim, AInput);
  end
  else
  begin
    iPos := Pos(ADelim, AInput);
  end;
  if iPos = 0 then
  begin
    Result := AInput;
    if ADelete then
    begin
      AInput := '';
    end;
  end
  else
  begin
    Result := Copy(AInput, 1, iPos - 1);
    if ADelete then
    begin
      Delete(AInput, 1, iPos + Length(ADelim) - 1);
    end;
  end;
end;

procedure TranslateStringToTInAddr(AIP: string; var AInAddr);
var
  phe: PHostEnt;
  pac: PChar;
  GInitData: TWSAData;
begin
  WSAStartup($101, GInitData);
  try
    phe := GetHostByName(PChar(AIP));
    if Assigned(phe) then
    begin
      pac := phe^.h_addr_list^;
      if Assigned(pac) then
      begin
        with TIPAddr(AInAddr).S_un_b do
        begin
          s_b1 := byte(pac[0]);
          s_b2 := byte(pac[1]);
          s_b3 := byte(pac[2]);
          s_b4 := byte(pac[3]);
        end;
      end
      else
      begin
        raise Exception.Create('Error getting IP from HostName');
      end;
    end
    else
    begin
      raise Exception.Create('Error getting HostName');
    end;
  except
    FillChar(AInAddr, SizeOf(AInAddr), #0);
  end;
  WSACleanup;
end;

function Ping(InetAddress: string; iTimeout: cardinal): boolean;
var
  hIcmpDll: HMODULE;
  hIcmpFile: THandle;
  InAddr: IPAddr;
  DW: DWORD;
  rep: array[1..128] of byte;
begin
  Result := False;
  { load a library }
  hIcmpDll := LoadLibrary('icmp.dll');

  if (hIcmpDll = 0) then
  begin
    raise Exception.Create('icmp.dll library can not be loaded or not found. ' +
      SysErrorMessage(GetLastError));
  end;

  try
    { load an address of required procedure}
    @IcmpCreateFile := GetProcAddress(hIcmpDll, 'IcmpCreateFile');
    @IcmpSendEcho := GetProcAddress(hIcmpDll, 'IcmpSendEcho');
    @IcmpCloseHandle := GetProcAddress(hIcmpDll, 'IcmpCloseHandle');

    {if procedure is found in the dll}
    if Assigned(IcmpCreateFile) and Assigned(IcmpSendEcho) and Assigned(IcmpCloseHandle)
      then
    begin
      hIcmpFile := IcmpCreateFile;
      try
        if hIcmpFile = INVALID_HANDLE_VALUE then
          Exit;
        TranslateStringToTInAddr(InetAddress, InAddr);
        DW := IcmpSendEcho(hIcmpFile, InAddr, nil, 0, nil, @rep, 128, iTimeout); //0);
        Result := (DW <> 0);
      finally
        IcmpCloseHandle(hIcmpFile);
      end;
    end;
  finally
    {unload a library}
    FreeLibrary(hIcmpDll);
  end;

end;

end.