2

我正在使用 TIdStack.LocalAddress 获取本地 IP 地址。在同时具有 IP6 和 IP4 的 OS X 系统上,这将返回 IP6 地址,这不是我想要的。

找到本地 IP4 地址的最佳方法是什么?例如,我可以简单地使用 TIdStack.LocalAddresses 中的最短条目。

4

1 回答 1

4

TIdStack.LocalAddress属性仅返回属性中列出的第一个 IP TIdStack.LocalAddresses(注意 - 这些属性已被弃用,因为它们不是线程安全的。您应该改用该TIdStack.AddLocalAddressesToList()方法)。一台PC/设备可以有多个本地IP,比如它连接到多个网络,同时支持IPv4和IPv6等。LocalAddresses列表中IP的顺序由操作系统决定,而不是由Indy决定。从它的声音来看,您将必须获得完整的列表并循环查找您感兴趣的 IPv4 地址。

TIdStackVCLPosix,Indy 用于 Mac OSX,实际上是目前唯一支持TIdStack在属性中报告 IPv4 和 IPv6 地址的实现LocalAddresses(其他TIdStack实现目前仅支持 IPv4)。但是,该列表是普通的TStrings,它不区分给定 IP 是 IPv4 还是 IPv6(它不使用该TStrings.Objects属性来提供该信息)。如果需要区分,则必须手动解析 IP。在未来的版本中,Indy 将使用TIdStack.LocalAddress(es)本机提供 IP 版本信息的不同实现来替换属性。

例如:

var
  IPs: TStringList;
  IP: String;
  I: Integer;
  Err: Boolean;
begin
  IPs := TStringList.Create;
  try
    GStack.AddLocalAddressesToList(IPs);
    for I := 0 to IPs.Count-1 do
    begin
      IP := IPs[I];

      // TIdStack.IsIP() currently only supports IPv4, but
      // it will be updated to support IPv6 in a future
      // release...
      //
      // if GStack.IsIP(IP) then
      // if GStack.IsIPv4(IP) then

      IPv4ToDWord(IP, Err);
      if not Err then 
        Break;
      IP := '';

      // alternatively:
      {
      IPAddr := TIdIPAddress.MakeAddressObject(IPs[I]);
      IP := IPAddr.IPv4AsString; // returns blank if not IPv4
      IPAddr.Free;
      if IP <> '' then
        Break;
      }
    end;
  finally
    IPs.Free;
  end;
  if IP <> '' then
  begin
    // use IP as needed...
  end;
end;
于 2013-02-25T20:24:04.523 回答