我正在使用TIdStack.LocalAddress获取本地IP地址。在同时具有IP6和IP4的OS X系统上,这将返回IP6地址,这不是我想要的。
找到本地IP4地址的最佳方法是什么?例如,我可以简单地使用TIdStack.LocalAddresses中的最短条目。
答案 0 :(得分:4)
TIdStack.LocalAddress
属性只返回TIdStack.LocalAddresses
属性中列出的第一个IP(注意 - 这些属性已弃用,因为它们不是线程安全的。您应该使用TIdStack.AddLocalAddressesToList()
方法而不是)。 PC /设备可以有多个本地IP,例如,如果它连接到多个网络,支持IPv4和IPv6等。LocalAddresses
列表中的IP顺序由操作系统决定,而不是由Indy决定。从它的声音,你将不得不获得完整的列表,并循环查找你感兴趣的IPv4地址。
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;