5

を使用して IP アドレスを取得しようとしていますNSHost。このNSHostオブジェクトでは、addresses メソッドを使用してオブジェクトの配列にアクセスできます。そのうちの 1 つは 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 *stringAddress; 他の場所で宣言されています

于 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 に答える
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 に答える
0

私の最初の答えは、たとえばルーターからプライベートネットワーク上のマシンに割り当てられたプライベートIPアドレスを提供することです。

インターネットに面しているパブリック IP を見たい場合。通常、サービス プロバイダーによって割り当てられます。Jim Doveyの回答をご覧になることをお勧めします -->こちら

私はそれをテストし、うまくいきましたが、パブリックIPを取得しようとする際のあいまいさを指摘する残りのコメントと回答を読んでください.

于 2010-07-19T19:43:12.837 に答える
0

上記の質問に対する回答が述べているように、1 台のマシンが持つことができる IP アドレスにはさまざまなものがあります。それが必要な場合はnames、NSHost のメソッドを使用して名前の配列を取得した方がよい場合があります。これをサフィックス (つまり *.lan) でフィルター処理して、これで必要なホストの名前を取得できます。名前。私の場合。.lan アドレスは、ネットワークの IP アドレスを点線のクワッドとして返します。

外部IPアドレスを見つけたい場合は、これが良い答えです.

于 2010-07-16T16:26:11.043 に答える