2015-05-29 4 views
0

Мне нужно получить IP-адрес устройства iOS. GStack.GetLocalAddressList возвращает все адреса, включая один для интерфейса Cellular. Как я могу получить адрес, связанный с интерфейсом wifi (en0)?IP-адрес устройства iOS

@widi если подобный вопрос был задан на другом языке платформы, это не значит, что есть ответ на один я указал - читать теги - это говорит «Дельфи» "FireMonkey ». Это как задать вопрос в C# и радоваться получению кода примера в COBOL.

+0

@DavidHeffernan курировал это один. Спасибо –

+0

Работает отлично. Спасибо вам за помощь Себастьяна. – DanielH

ответ

1

Вам нужно будет реализовать собственное перечисление IP-адресов, которое также возвращает информацию об адаптере. Вот пример:

uses IPAddressHelper, IdStack, IdGlobal; 

procedure TForm2.Button1Click(Sender: TObject); 
var 
    LocalIPs: TIdStackLocalAddressList; 
    I: Integer; 
begin 
    Memo1.Lines.Clear; 
    TIdStack.IncUsage; 
    try 
    LocalIPs := TIdStackLocalAddressList.Create; 
    try 
     GStack.GetLocalAddressList(LocalIPs); 
     for I := 0 to LocalIPs.Count - 1 do 
     begin 
     if LocalIPs[I] is TIdStackLocalAddressIPv4Ex then 
      Memo1.Lines.Add(TIdStackLocalAddressIPv4Ex(LocalIPs[I]).IfaName + LocalIPs[I].IPAddress + ' ' + BoolToStr(TIdStackLocalAddressIPv4Ex(LocalIPs[I]).IsWifi, True)); 
     end; 
    finally 
     LocalIPs.Free; 
    end; 
    finally 
    TIdStack.DecUsage; 
    end; 
end; 

Этот блок реализует расширенный класс Stack, который включает в себя имя адаптера и некоторые функции, которые помогают решить, если сеть сотовой связи или Wi-Fi.

unit IPAddressHelper; 

interface 

uses 
    Classes, 
    IdStack, 
    IdStackConsts, 
    IdGlobal, 
    IdStackBSDBase, 
    IdStackVCLPosix; 

type 
    TIdStackLocalAddressIPv4Ex = class(TIdStackLocalAddressIPv4) 
    protected 
    FFlags: Cardinal; 
    FIfaName: string; 
    public 
    function IsWifi: Boolean; 
    function IsPPP: Boolean; 
    property IfaName: string read FIfaName; 
    constructor Create(ACollection: TCollection; const AIPAddress, ASubNetMask: string; AName: MarshaledAString; AFlags: Cardinal); reintroduce; 
    end; 

    TIdStackLocalAddressIPv6Ex = class(TIdStackLocalAddressIPv6) 
    protected 
    FFlags: Cardinal; 
    FIfaName: string; 
    public 
    function IsWifi: Boolean; 
    function IsPPP: Boolean; 
    property IfaName: string read FIfaName; 
    constructor Create(ACollection: TCollection; const AIPAddress: string; AName: MarshaledAString; AFlags: Cardinal); reintroduce; 
    end; 

    TIdStackVCLPosixEx = class(TIdStackVCLPosix) 
    public 
    procedure GetLocalAddressList(AAddresses: TIdStackLocalAddressList); override; 
    end; 

implementation 

uses 
    Posix.Base, 
    Posix.NetIf, 
    Posix.NetinetIn, 
    SysUtils; 

function getifaddrs(ifap: pifaddrs): Integer; cdecl; external libc name _PU + 'getifaddrs'; {do not localize} 
procedure freeifaddrs(ifap: pifaddrs); cdecl; external libc name _PU + 'freeifaddrs'; {do not localize} 

procedure TIdStackVCLPosixEx.GetLocalAddressList(AAddresses: TIdStackLocalAddressList); 
var 
    LAddrList, LAddrInfo: pifaddrs; 
    LSubNetStr: String; 
begin 
    if getifaddrs(@LAddrList) = 0 then 
    try 
    AAddresses.BeginUpdate; 
    try 
     LAddrInfo := LAddrList; 
     repeat 
     if (LAddrInfo^.ifa_addr <> nil) and ((LAddrInfo^.ifa_flags and IFF_LOOPBACK) = 0) then 
     begin 
      case LAddrInfo^.ifa_addr^.sa_family of 
      Id_PF_INET4: begin 
       if LAddrInfo^.ifa_netmask <> nil then begin 
       LSubNetStr := TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_netmask)^.sin_addr, Id_IPv4); 
       end else begin 
       LSubNetStr := ''; 
       end; 
       TIdStackLocalAddressIPv4Ex.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In(LAddrInfo^.ifa_addr)^.sin_addr, Id_IPv4), LSubNetStr, LAddrInfo^.ifa_name, LAddrInfo^.ifa_flags); 
      end; 
      Id_PF_INET6: begin 
       TIdStackLocalAddressIPv6Ex.Create(AAddresses, TranslateTInAddrToString(PSockAddr_In6(LAddrInfo^.ifa_addr)^.sin6_addr, Id_IPv6), LAddrInfo^.ifa_name, LAddrInfo^.ifa_flags); 
      end; 
      end; 
     end; 
     LAddrInfo := LAddrInfo^.ifa_next; 
     until LAddrInfo = nil; 
    finally 
     AAddresses.EndUpdate; 
    end; 
    finally 
    freeifaddrs(LAddrList); 
    end; 
end; 

const 
    IFF_UP = $1; 
    IFF_BROADCAST = $2; 
    IFF_LOOPBACK = $8; 
    IFF_POINTOPOINT = $10; 
    IFF_MULTICAST = $8000; 

{ TIdStackLocalAddressIPv4Ex } 

constructor TIdStackLocalAddressIPv4Ex.Create(ACollection: TCollection; 
    const AIPAddress, ASubNetMask: string; AName: MarshaledAString; AFlags: Cardinal); 
begin 
    inherited Create(ACollection, AIPAddress, ASubnetMask); 
    FFlags := AFlags; 
    if Assigned(AName) then 
    FIfaName := AName; 
end; 

function TIdStackLocalAddressIPv4Ex.IsPPP: Boolean; 
// The network connection to the carrier is established via PPP 
// so GPRS, EDGE, UMTS connections have the flag IFF_POINTOPOINT set 
begin 
    Result := (FFlags and (IFF_UP or IFF_POINTOPOINT) = (IFF_UP or IFF_POINTOPOINT)) 
      and (FFlags and (IFF_LOOPBACK) = 0); 
end; 

function TIdStackLocalAddressIPv4Ex.IsWifi: Boolean; 
// WLAN connections support Multicast 
// WLAN connections do not use PPP 
// Filter out the loopback interface (just for completeness, in case the 
// network enumeration is changed so that loopback is also included) 
begin 
    Result := ((FFlags and (IFF_UP or IFF_MULTICAST)) = (IFF_UP or IFF_MULTICAST)) 
     and (FFlags and (IFF_LOOPBACK or IFF_POINTOPOINT) = 0); 
end; 

{ TIdStackLocalAddressIPv6Ex } 

constructor TIdStackLocalAddressIPv6Ex.Create(ACollection: TCollection; 
    const AIPAddress: string; AName: MarshaledAString; AFlags: Cardinal); 
begin 
    inherited Create(ACollection, AIPAddress); 
    FFlags := AFlags; 
    if Assigned(AName) then 
    FIfaName := AName; 
end; 

function TIdStackLocalAddressIPv6Ex.IsPPP: Boolean; 
begin 
    Result := (FFlags and (IFF_UP or IFF_POINTOPOINT) = (IFF_UP or IFF_POINTOPOINT)) 
      and (FFlags and (IFF_LOOPBACK) = 0); 
end; 

function TIdStackLocalAddressIPv6Ex.IsWifi: Boolean; 
begin 
    Result := ((FFlags and (IFF_UP or IFF_MULTICAST)) = (IFF_UP or IFF_MULTICAST)) 
     and (FFlags and (IFF_LOOPBACK or IFF_POINTOPOINT) = 0); 
end; 

initialization 
    SetStackClass(TIdStackVCLPosixEx); 
end. 

Пожалуйста, имейте в виду, что интерфейс Wi-Fi может также использовать дозированный соединение, если он подключается к беспроводной точке доступа.

Смежные вопросы