iPad: 如何通过编程获取以太网IP地址

5

我知道如何通过en0接口获取IP地址,可以在此处看到:iPhone/iPad/OSX: How to get my IP address programmatically?

但是现在我正在使用Lightning转USB 3相机适配器实施与LAN的以太网连接,以便在9.3中无需Wifi连接即可连接到互联网,因此上述解决方案无法在没有无线连接的情况下解析IP地址。 iPad已经可以正常上网,现在很重要的是应用程序可以解析设备自己的IP地址。

如何通过Lightning-> USB-> Ethernet连接获取iPad的IP地址? 而不是无线方式。
提前致谢!

2个回答

9

en2接口。

添加:

[[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en2"]

iPhone/iPad/OSX: How to get my IP address programmatically? 中的第一种解决方案,可以通过有线连接获取设备的IP地址。

更新:扩展@Raptor上面链接的解决方案;如果无线和有线IP地址都存在,则会返回两者IP地址。然后只需检查返回字典值的长度即可确定使用哪个IP地址。

#import <ifaddrs.h>
#import <arpa/inet.h>

+ (NSDictionary *)getBothIPAddresses {
    const NSString *WIFI_IF = @"en0";
    NSArray *KNOWN_WIRED_IFS = @[@"en1",@"en2",@"en3",@"en4"];
    NSArray *KNOWN_CELL_IFS = @[@"pdp_ip0",@"pdp_ip1",@"pdp_ip2",@"pdp_ip3"];

    const NSString *UNKNOWN_IP_ADDRESS = @"";

    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithDictionary:@{@"wireless":UNKNOWN_IP_ADDRESS,
                                                                                        @"wired":UNKNOWN_IP_ADDRESS,
                                                                                         @"cell":UNKNOWN_IP_ADDRESS}];

    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    // retrieve the current interfaces - returns 0 on success
    success = getifaddrs(&interfaces);
    if (success == 0) {
        // Loop through linked list of interfaces
        temp_addr = interfaces;
        while(temp_addr != NULL) {
            if (temp_addr->ifa_addr == NULL) {
                 temp_addr = temp_addr->ifa_next;
                 continue;
            }
            if(temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:WIFI_IF]) {
                    // Get NSString from C String
                    [addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"wireless"];
                
                }
                // Check if interface is a wired connection
                if([KNOWN_WIRED_IFS containsObject:[NSString stringWithUTF8String:temp_addr->ifa_name]]) {
                    [addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"wired"];
                }
                // Check if interface is a cellular connection
                if([KNOWN_CELL_IFS containsObject:[NSString stringWithUTF8String:temp_addr->ifa_name]]) {
                    [addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"cell"];
                }
            }

            temp_addr = temp_addr->ifa_next;
        }
    }
    // Free memory
    freeifaddrs(interfaces);

    return addresses;
}

更新: en3 接口,另一种可能性;似乎取决于适配器类型。这让我想到可能还有其他接口我还没有发现,基于使用的硬件,请在评论中指出。

更新: 也是 en4;不像我最初认为的那样取决于适配器,因为某个时刻拥有完全相同硬件的 Mini 决定从一个接口切换到这个新接口。此外,我开始认为只需将 ifa_name 与任何格式为 en[2..n] 的字符串进行比较,只要它位于 AF_INET 家族(例如,en1 不是,并且不返回我们正在寻找的地址);如果没有更多证据,实现类似于 Prod 的东西可能为时过早,因此现在我使用“已知”有线接口列表来管理。

更新: 还考虑了移动 AF_INET 接口,在iOS 网络接口名称的确切含义是什么?什么是 pdp_ip?什么是 ap? 中提到。

更新: 以太网 IP 地址最近开始出现在某些新 iPad 上的 en1 接口上,因此在它是 AF_INET 家族成员时也应该考虑。没有可区分的韵律或原因,它会发生在不同的 iPad 型号和 iOS 版本中。


我已经让这段代码运行起来了,但是我注意到当iPad通过USB线连接时(而不是以太网适配器),会出现一个名为“en2”的接口,并带有一个IP地址。然而,如果我尝试在此接口上打开套接字,则会收到“无法路由到主机”的错误。除了尝试通过它们建立连接之外,是否有任何方法可以检测和过滤这些接口? - bugloaf

2

已更新至Swift 3

 import arpa
    import ifaddrs
    
    class func getBothIPAddresses() -> [AnyHashable: Any] {
        let WIFI_IF: String = "en0"
        let KNOWN_WIRED_IFS: [Any] = ["en2", "en3", "en4"]
        let KNOWN_CELL_IFS: [Any] = ["pdp_ip0", "pdp_ip1", "pdp_ip2", "pdp_ip3"]
        let UNKNOWN_IP_ADDRESS: String = ""
        var addresses: [AnyHashable: Any] = ["wireless": UNKNOWN_IP_ADDRESS, "wired": UNKNOWN_IP_ADDRESS, "cell": UNKNOWN_IP_ADDRESS]
    
        var interfaces: ifaddrs? = nil
    
        var temp_addr: ifaddrs? = nil
        var success: Int = 0
        // retrieve the current interfaces - returns 0 on success
        success = getifaddrs(interfaces)
        if success == 0 {
            // Loop through linked list of interfaces
            temp_addr = interfaces
            while temp_addr != nil {
                if temp_addr?.ifa_addr == nil {
                    temp_addr = temp_addr?.ifa_next
                    continue
                }
                if temp_addr?.ifa_addr?.sa_family == AF_INET {
                    // Check if interface is en0 which is the wifi connection on the iPhone
                    if (String(utf8String: temp_addr?.ifa_name) == WIFI_IF) {
                        // Get NSString from C String
                        addresses["wireless"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
                    }
                    // Check if interface is a wired connection
                    if KNOWN_WIRED_IFS.contains(String(utf8String: temp_addr?.ifa_name)) {
                        addresses["wired"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
                    }
                    // Check if interface is a cellular connection
                    if KNOWN_CELL_IFS.contains(String(utf8String: temp_addr?.ifa_name)) {
                        addresses["cell"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
                    }
                }
                temp_addr = temp_addr?.ifa_next
            }
        }
            // Free memory
        freeifaddrs(interfaces)
        return addresses
    }

我找不到名为arpa的模块。 - Egle Matutyte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接