ios - 使用 Objective-C 获取 ip 范围

标签 ios objective-c networking

我做的是小型 iPhone 应用程序,我需要获取 IP 范围并使用 Objective-C 对其进行迭代。我可以获得本地 IP、网络掩码。我还在 SO 解决方案上找到了如何获取广播地址。但我怎样才能获得网络地址呢?通过了解本地网络中第一个的网络地址和本地网络中最后一个广播地址,我想迭代该范围内的所有 IP。只需调用它并查看响应即可。我怎样才能做到这一点?

https://stackoverflow.com/a/21077257 获取广播的解决方案

#include <net/ethernet.h>
#include <arpa/inet.h>

NSString *localIPAddress = @"192.168.1.10";
NSString *netmaskAddress = @"255.255.192.0";

// Strings to in_addr:
struct in_addr localAddr;
struct in_addr netmaskAddr;
inet_aton([localIPAddress UTF8String], &localAddr);
inet_aton([netmaskAddress UTF8String], &netmaskAddr);

// The broadcast address calculation:
localAddr.s_addr |= ~(netmaskAddr.s_addr);

// in_addr to string:
NSString *broadCastAddress = [NSString stringWithUTF8String:inet_ntoa(localAddr)];

更新:从 netmaskAddress 我可以得到网络中的主机数量。我只需要使用 IP 即可。现在的问题是如何从给定的 IP 中获取下一个 IP?例如我有

NSString *ip = "192.168.1.5"

如何使用 Objective-C 获取“192.168.1.6”?

最佳答案

我不建议对这种 IP (in_addr) 进行位操作,因为如果你看一下内部字节是反向排序的。

下面的代码打印设备 ip、网络 ip、网络掩码和广播地址以及网络范围内的所有 ip。这可能会有帮助。享受吧!

NetworkInformation *network = [[NetworkInformation alloc] init];
NSLog(@"%@", network);
for(NSString *ip in network.ipsInRange){
    NSLog(@"ip: %@", ip);
}

网络信息.h

#import <Foundation/Foundation.h>

@interface NetworkInformation : NSObject
@property (nonatomic, retain) NSString *deviceIP;
@property (nonatomic, retain) NSString *netmask;
@property (nonatomic, retain) NSString *address;
@property (nonatomic, retain) NSString *broadcast;
@property (nonatomic, retain) NSArray *ipsInRange;
- (void)updateData;
- (NSString *)description;
@end

网络信息.m

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

@implementation NetworkInformation

- (id)init {
    self = [super init];
    if (self) {
        [self updateData];
    }
    return self;
}

-(void)updateData {
    [self updateDataFromWifiNetwork];
    self.address = [self getNetworkAddress];
    self.ipsInRange = [self getIPsInRange];
}

- (void)updateDataFromWifiNetwork {
    self.deviceIP = nil;
    self.netmask = nil;
    self.broadcast = nil;
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    success = getifaddrs(&interfaces);
    if (success == 0){
        temp_addr = interfaces;
        while(temp_addr != NULL){
            if(temp_addr->ifa_addr->sa_family == AF_INET){
                if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]){
                    self.deviceIP = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                    self.netmask = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_netmask)->sin_addr)];
                    self.broadcast = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_dstaddr)->sin_addr)];
                }
            }
            temp_addr = temp_addr->ifa_next;
        }
    }
    freeifaddrs(interfaces);
    if(!self.deviceIP || !self.netmask){
        NSLog(@"error in updateDataFromWifiNetwork, device ip: %@ netmask: %@", self.deviceIP, self.netmask);
    }
}

-(NSString*)getNetworkAddress {
    if(!self.deviceIP || !self.netmask){
        return nil;
    }
    unsigned int address = [self convertSymbolicIpToNumeric:self.deviceIP];
    address &= [self convertSymbolicIpToNumeric:self.netmask];
    return [self convertNumericIpToSymbolic:address];
}

-(NSArray*)getIPsInRange {
    unsigned int address = [self convertSymbolicIpToNumeric:self.address];
    unsigned int netmask = [self convertSymbolicIpToNumeric:self.netmask];
    NSMutableArray *result = [[NSMutableArray alloc] init];
    int numberOfBits;
    for (numberOfBits = 0; numberOfBits < 32; numberOfBits++) {
        if ((netmask << numberOfBits) == 0){
            break;
        }
    }
    int numberOfIPs = 0;
    for (int n = 0; n < (32 - numberOfBits); n++) {
        numberOfIPs = numberOfIPs << 1;
        numberOfIPs = numberOfIPs | 0x01;
    }
    for (int i = 1; i < (numberOfIPs) && i < numberOfIPs; i++) {
        unsigned int ourIP = address + i;
        NSString *ip = [self convertNumericIpToSymbolic:ourIP];
        [result addObject:ip];
    }
    return result;
}

-(NSString*)convertNumericIpToSymbolic:(unsigned int)numericIP {
    NSMutableString *sb = [NSMutableString string];
    for (int shift = 24; shift > 0; shift -= 8) {
        [sb appendString:[NSString stringWithFormat:@"%d", (numericIP >> shift) & 0xff]];
        [sb appendString:@"."];
    }
    [sb appendString:[NSString stringWithFormat:@"%d", (numericIP & 0xff)]];
    return sb;
}

-(unsigned int)convertSymbolicIpToNumeric:(NSString*)symbolicIP {
    NSArray *st = [symbolicIP componentsSeparatedByString: @"."];
    if (st.count != 4){
        NSLog(@"error in convertSymbolicIpToNumeric, splited string count: %lu", st.count);
        return 0;
    }
    int i = 24;
    int ipNumeric = 0;
    for (int n = 0; n < st.count; n++) {
        int value = [(NSString*)st[n] intValue];
        if (value != (value & 0xff)) {
            NSLog(@"error in convertSymbolicIpToNumeric, invalid IP address: %@", symbolicIP);
            return 0;
        }
        ipNumeric += value << i;
        i -= 8;
    }
    return ipNumeric;
}

-(NSString*)description {
    return [NSString stringWithFormat: @"\nip:%@\nnetmask:%@\nnetwork:%@\nbroadcast:%@", self.deviceIP, self.netmask, self.address, self.broadcast];
}

@end

关于ios - 使用 Objective-C 获取 ip 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21754612/

相关文章:

linux - 什么是 TCP 中的最大段生命周期 (MSL)?

ios - APNs 是否适用于使用 Enterprise Distribution 程序在内部分发的应用程序?

ios - 根据启动参数定义快速类型别名

ios - UITableview heightForRowAtIndexPath : reloads label in cell

ios - UIImageView 在 UIView 中的位置完全错误

networking - 为什么UDP+软件可靠点餐系统比TCP快?

c++ - 如何将 4 个字节复制到 sockaddr.sa_data?

ios - 单击 tableView 中的文本字段时,ScrollView 没有向上移动

ios - 函数指针声明编译错误

iphone - 允许对象类型为 'id' 还是为方法的两种不同类型提供两个参数更好?