【发布时间】:2022-10-13 05:19:16
【问题描述】:
仿照@Remy Lebeau 在this SO item 中非常有用的代码示例,我有以下函数,它在 Windows 10 中按预期工作返回;例如。:
No of Addresses: 4
IPv4 Addresses:
IP Address #0: 192.168.56.1 - 255.255.255.0 - 11
IP Address #1: 192.168.1.7 - 255.255.255.0 - 8
IP: 192.168.56.1
但是,当我将平台更改为 Android 64 位并在我的三星 S21 上运行它,同时启用 WiFi 并连接到我的 LAN 时,它只返回本地环回 IP 而没有其他值;例如。:
No of Addresses: 1
IPv4 Addresses:
IP Address #0: 127.0.0.1 - - 0
IP: 127.0.0.1
我曾希望这与缺乏一些许可有关,但正如 Remy 在评论中指出的那样,问题在于 Android 的 Indy10 方法已损坏,需要使用以下 Dave Nottage 的解决方法。 (如果您还想获得 Indy 方法应该返回的 NetMask,则需要进一步的工作。如果/当我把它弄出来时,我会在此处发布我的解决方案作为答案)
function getLocalIP: string;
begin
Result := '';
try
var IPList := TIdStackLocalAddressList.Create;
try
TIdStack.IncUsage;
try
GStack.GetLocalAddressList(IPList);
finally
TIdStack.DecUsage;
end;
WriteLog('DEBUG', 'No of Addresses: ' + IntToStr(IPList.Count));
WriteLog('DEBUG', 'IPv4 Addresses:');
var IPStrings := TStringList.Create;
try
for var i in IPList do
begin
if TIdStackLocalAddressIPv4(i).IPVersion = Id_IPv4 then
begin
IPStrings.Add(TIdStackLocalAddressIPv4(i).IPAddress + ' - ' + TIdStackLocalAddressIPv4(i).SubNetMask
+ ' - ' + TIdStackLocalAddressIPv4(i).InterfaceIndex.ToString);
end;
end;
// show IP Addresses in the log file
for var i := 0 to IPStrings.Count-1 do
WriteLog('DEBUG', 'IP Address #' + IntToStr(i) + ': ' + IPStrings[i]);
Result := IPStrings[0].Split([' - '])[0];
WriteLog('DEBUG', 'IP: ' + Result);
finally
IPStrings.Free;
end;
finally
IPList.Free;
end;
except
On E: Exception do
begin
Result := '';
WriteLog('ERROR', 'IP Error: ' + E.message);
end;
end;
end;
【问题讨论】:
-
我真的很感谢@DaveNottage 的快速回答,我希望他的代码能解决问题。但是,我注意到使用该代码将需要编译器指令来选择适合每个平台的源代码段(我最终也希望使用 iOS)。在戴夫的要点发布 5 年后,现在 TIdStack 是否仍然存在问题?
-
感谢您确认它在 Android 中仍然存在问题。它现在适用于 iOS 吗?
-
AFAIK,是的。它在 iOS(以及 OSX、Linux 和 FreeBSD)上使用
getifaddrs()