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

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

最佳答案

TIdStack.LocalAddress属性仅返回TIdStack.LocalAddresses属性中列出的第一个IP(请注意-不推荐使用这些属性,因为它们不是线程安全的。应改用TIdStack.AddLocalAddressesToList()方法)。 PC /设备可以具有多个本地IP,例如是否连接到多个网络,同时支持IPv4和IPv6等。LocalAddresses列表中IP的顺序由操作系统而不是由Indy确定。从它的声音中,您将必须获取完整的列表,并在其中循环查找所需的IPv4地址。

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

例如:

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;

关于macos - 如何使用Indy获取本地IP4地址?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15071564/

10-09 16:56