5

我正在尝试使用NSHost. 使用该NSHost对象,我可以使用addresses 方法访问一个对象数组,其中一个是IP 地址。我担心 IP 地址可能会在阵列中从一台机器更改为另一台机器。有没有办法以通用的方式访问这些信息?

在之前的帖子中曾尝试回答这个问题,但正如您所见,它还不够。

IP地址?- 可可

这是我的代码:

+(NSString *) ipAddress {
    NSHost * h = [[[NSHost currentHost] addresses] objectAtIndex:1];
    return h ;  
}
4

7 回答 7

12

我唯一能想到的就是使用“ http://www.dyndns.org/cgi-bin/check_ip.cgi ”之类的东西,其他人可能有更好的方法。

这是一个例子,(即快速拼凑的代码)

NSUInteger  an_Integer;
NSArray * ipItemsArray;
NSString *externalIP;

NSURL *iPURL = [NSURL URLWithString:@"http://www.dyndns.org/cgi-bin/check_ip.cgi"];

if (iPURL) {
    NSError *error = nil;
    NSString *theIpHtml = [NSString stringWithContentsOfURL:iPURL 
                                                  encoding:NSUTF8StringEncoding 
                                                     error:&error];
    if (!error) {
                NSScanner *theScanner;
        NSString *text = nil;

        theScanner = [NSScanner scannerWithString:theIpHtml];

        while ([theScanner isAtEnd] == NO) {

                // find start of tag
            [theScanner scanUpToString:@"<" intoString:NULL] ; 

                // find end of tag
            [theScanner scanUpToString:@">" intoString:&text] ;

                // replace the found tag with a space
                //(you can filter multi-spaces out later if you wish)
            theIpHtml = [theIpHtml stringByReplacingOccurrencesOfString:
                    [ NSString stringWithFormat:@"%@>", text]
                                                   withString:@" "] ;
            ipItemsArray =[theIpHtml  componentsSeparatedByString:@" "];
            an_Integer=[ipItemsArray indexOfObject:@"Address:"];

                externalIP =[ipItemsArray objectAtIndex:  ++an_Integer];



        } 


            NSLog(@"%@",externalIP);
    } else {
        NSLog(@"Oops... g %d, %@", 
              [error code], 
              [error localizedDescription]);
    }
}




[pool drain];
return 0;}
于 2010-07-21T15:46:09.727 回答
9

我在很多机器上都用过这个,没有问题。

 -(void) getIPWithNSHost{
    NSArray *addresses = [[NSHost currentHost] addresses];

for (NSString *anAddress in addresses) {
    if (![anAddress hasPrefix:@"127"] && [[anAddress componentsSeparatedByString:@"."] count] == 4) {
         stringAddress = anAddress;
        break;
    } else {
        stringAddress = @"IPv4 address not available" ;
    }
}
        //NSLog (@"getIPWithNSHost: stringAddress = %@ ",stringAddress);    

}

NSString *字符串地址;在其他地方声明

于 2010-07-16T20:16:23.427 回答
1

我想更新关于获取外部 IP 的原始答案。

没有太大变化,但我想展示如何使用NSXMLDocumentXquary获取和解析 HTML

这也提供了一个小例子,说明如何通过获取节点来解析 HTML。在我看来,这更直接。虽然 NSXMLDocument 最初是针对 XML 的,但它会解析 HTML DOM 树

    NSString *externalIP;

    ///--DYNDNS.ORG  URL

    NSURL *iPURL = [NSURL URLWithString:@"http://www.dyndns.org/cgi-bin/check_ip.cgi"];
    if (iPURL) {

        NSError *err_p = nil;


        //--use NSXMLDocument to get the url:(*Requests NSXMLNode to preserve whitespace characters (such as tabs and carriage returns) in the XML source that are not part of node content*)
    NSXMLDocument * xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:iPURL
                                                                  options:(NSXMLNodePreserveWhitespace|
                                                                           NSXMLNodePreserveCDATA)
                                                                    error:&err_p];

    if (xmlDoc == nil) {

        //-- That did not work so lets see if we can change the malformed XML into valid XML during processing of the document.
        xmlDoc = [[NSXMLDocument alloc] initWithContentsOfURL:iPURL
                                                      options:NSXMLDocumentTidyXML
                                                        error:&err_p];

    }


    if (!err_p) {
 NSError * error;
        //-- We will use XQuary to get the text from the child node. Dyndns.org page is very simple. So we just need to get the Body text.

    NSString *xpathQueryTR =  @"//body/text()";
        //-- we get the first node's string value. We use string value to in effect cast to NSString.
        //We the seperate the string into components using a space. and obtain the last object in the returned array.
        //--This gives us the IP string without the "Current IP Address:" string.
    externalIP = [[[[[xmlDoc nodesForXPath:xpathQueryTR error:&error]objectAtIndex:0] stringValue]componentsSeparatedByString:@" "]lastObject];

    if (!error) {

    NSLog(@"%@",externalIP);

    }else {
        NSLog(@"Oops... g %ld, %@",
              (long)[error code],
              [error localizedDescription]);
    }

    }else {
        NSLog(@"Oops... g %ld, %@",
              (long)[err_p code],
              [err_p localizedDescription]);
    }
}
于 2014-04-04T12:09:33.337 回答
1

制作了一个实用程序类来查找 IP 地址。简约的方法。您可以使用更多条件或正则表达式检查来加强它。

 NSLog(@"Addresses: %@", [[NSHost currentHost] addresses]);

这是 NSHost 返回的列表

 "fe80::1610:9fff:fee1:8c2f%en0",
 "192.168.212.61",
 "fe80::2829:3bff:fee6:9133%awdl0",
 "fe80::e54b:8494:bbc8:3989%utun0",
 "fd68:cc16:fad8:ded9:e54b:8494:bbc8:3989",
 "10.11.51.61",
 "::1",
 "127.0.0.1",
 "fe80::1%lo0"

测试方法,

- (void)testHost {
    NSLog(@"Addresses: %@", [[NSHost currentHost] addresses]);

    for (NSString *s in [[NSHost currentHost] addresses]) {
        IPAddress *addr = [[IPAddress alloc] initWithString:s];
        if (![addr isLocalHost] && [addr isIPV4]) {
            // do something
        }
    }
}

IP地址.h

#import <Foundation/Foundation.h>

@interface IPAddress : NSObject

@property (nonatomic, strong) NSString *IPAddress;

- (id)initWithString:(NSString *)ipaddress;

- (BOOL)isLocalHost;
- (BOOL) isIPV4;
- (BOOL) isIPV6;

@end

IP地址.m

#import "IPAddress.h"

@implementation IPAddress

- (id)initWithString:(NSString *)ipaddress {
    self = [super init];
    if (self) {
        self.IPAddress = ipaddress;
    }
    return self;
}

- (BOOL)isLocalHost {
    if (self.IPAddress == nil) return NO;
    if ([@"127.0.0.1" compare:self.IPAddress options:NSCaseInsensitiveSearch] == NSOrderedSame) {
        return YES;
    }

    if ([@"localhost" compare:self.IPAddress options:NSCaseInsensitiveSearch] == NSOrderedSame) {
        return YES;
    }

    if ([@"::1" compare:self.IPAddress options:NSCaseInsensitiveSearch] == NSOrderedSame) {
        return YES;
    }

    return NO;
}

- (BOOL) isIPV4 {
    NSArray *ar = [self.IPAddress componentsSeparatedByString:@"."];
    if (ar.count == 4) {
        return YES;
    }
    return NO;
}

- (BOOL) isIPV6 {
    if (![self isIPV4]) {
        if ([self.IPAddress rangeOfString:@":"].location != NSNotFound) {
            return YES;
        }
    }
    return NO;
}

@end
于 2015-09-22T09:59:13.840 回答
0

正如您上面提到的问题的答案所说,一台机器可以拥有多种IP地址。如果这是您想要的,那么您最好使用namesNSHost 的方法来获取名称数组,然后您可以过滤后缀(即 *.lan)以获取您想要的主机名称姓名。就我而言。.lan 地址以虚线四边形返回我的网络 IP 地址。

如果您想查找外部 IP 地址,那么这是一个很好的答案

于 2010-07-16T16:26:11.043 回答
0

我的第一个答案是提供从您的路由器分配给专用网络上机器的专用 IP 地址。

如果你想看到公网IP,它是面向互联网的。通常由您的服务提供商分配。您可能想看看 Jim Dovey的答案-->这里

我对其进行了测试并且效果很好,但是阅读了其余的评论和答案,这些评论和答案指出了在尝试获得公共 IP 时的含糊不清。

于 2010-07-19T19:43:12.837 回答
0

您可以在 NSHost 上创建一个类别并执行以下操作:

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

。H

+ (NSDictionary *) interfaceIP4Addresses;
+ (NSDictionary *) interfaceIP6Addresses;
+ (NSDictionary *) interfaceIPAddresses;

.m

typedef NS_ENUM(NSUInteger, AddressType) {

    AddressTypeBoth     = 0,
    AddressTypeIPv4     = 1,
    AddressTypeIPv6     = 2
};

@implementation SomeClass

#pragma mark - Helper Methods:

+ (NSDictionary *) _interfaceAddressesForFamily:(AddressType)family {

    NSMutableDictionary *interfaceInfo = [NSMutableDictionary dictionary];
    struct ifaddrs *interfaces;

    if ( (0 == getifaddrs(&interfaces)) ) {

        struct ifaddrs *interface;

        for ( interface=interfaces; interface != NULL; interface=interface->ifa_next ) {

            if ( (interface->ifa_flags & IFF_UP) && !(interface->ifa_flags & IFF_LOOPBACK) ) {

                const struct sockaddr_in *addr = (const struct sockaddr_in *)interface->ifa_addr;

                if ( addr && addr->sin_family == PF_INET ) {

                    if ( (family == AddressTypeBoth) || (family == AddressTypeIPv4) ) {
                        char ip4Address[INET_ADDRSTRLEN];
                        inet_ntop( addr->sin_family, &(addr->sin_addr), ip4Address, INET_ADDRSTRLEN );

                        [interfaceInfo setObject:[NSString stringWithUTF8String:interface->ifa_name]
                                          forKey:[NSString stringWithUTF8String:ip4Address]];

                } } else if ( addr && addr->sin_family == PF_INET6 ) {

                    if ( (family == AddressTypeBoth) || (family == AddressTypeIPv6) ) {
                        char ip6Address[INET6_ADDRSTRLEN];
                        inet_ntop( addr->sin_family, &(addr->sin_addr), ip6Address, INET6_ADDRSTRLEN );

                        [interfaceInfo setObject:[NSString stringWithUTF8String:interface->ifa_name]
                                          forKey:[NSString stringWithUTF8String:ip6Address]];
                } }
            }

        } freeifaddrs( interfaces );

    } return [NSDictionary dictionaryWithDictionary:interfaceInfo];
}

#pragma mark - Class Methods:

+ (NSDictionary *) interfaceIP4Addresses { return [self _interfaceAddressesForFamily:AddressTypeIPv4]; }
+ (NSDictionary *) interfaceIP6Addresses { return [self _interfaceAddressesForFamily:AddressTypeIPv6]; }
+ (NSDictionary *) interfaceIPAddresses  { return [self _interfaceAddressesForFamily:AddressTypeBoth]; }

@end

这真的很快而且很好。如果您需要其他信息或进行监控,请使用系统配置框架。

于 2013-02-04T23:09:31.093 回答