【问题标题】:IP Address? - CocoaIP地址? - 可可
【发布时间】:2010-11-22 20:19:19
【问题描述】:

如何制作一个通过单击按钮显示您的 IP 地址的 GUI 程序?拜托,不难解释,我不久前才开始使用 Cocoa。

谢谢,

凯文

【问题讨论】:

  • 他想在没有 VB 的 Mac 上执行此操作。
  • 是的,我已经在 Visual Basic 中完成了 IP 的事情,但我想尝试在 Cocoa 中完成它
  • 让我帮你拿那个...youtube.com/watch?v=hkDD03yeLnU

标签: objective-c cocoa xcode user-interface


【解决方案1】:

您可以通过两种方式获取IP地址:

1-如果要获取当前使用的网络上的本地ip地址,可以使用以下方法进行检索:

-(NSString *)getIPAddress
{
    NSString *address = @"error";
    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->sa_family == AF_INET)
            {
                    // Get NSString from C String
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
            }
            temp_addr = temp_addr->ifa_next;
        }
    }

    // Free memory
    freeifaddrs(interfaces);
    return address;
}

2-如果要获取外部IP地址,则需要使用以下方法:

-(NSString*)getIP
{
    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]);
        }
    }
    return externalIP;
}

【讨论】:

  • 只有在getifaddrs() 成功的情况下才应该调用freeifaddrs()
【解决方案2】:

为了确定IP地址,我发现 this.

至于将其制作成 Cocoa 应用程序,在 Interface Builder 的主窗口中添加一个 NSTextField(标签),放入一个按钮,添加一个应用程序控制器(您制作的 NSObject 的子类),输入出口和动作,进行正确的连接,并在“获取 IP”方法中,输入该代码并设置标签的 stringValue 的值。

您可以使用[[NSHost currentHost] address],但它并不总是显示您喜欢的内容。例如,在我的系统上,它提供了我的 IPv6 地址。

编辑:在我的系统上,[[[NSHost currentHost] addresses] objectAtIndex:0] 有我的 IPv4 地址。

【讨论】:

  • 对我来说,这不是第一个对象,而是最后一个。另外,我建议不要使用objectAtIndex,而是使用“lastObject”:[[[NSHost currentHost]addresses] lastObject]
  • 对我来说,这是 5 个索引中的第二个。如果您专门寻找 IPv4 或 IPv6 地址,可能需要进行一些验证。
【解决方案3】:

[[NSHost currentHost] addresses] 将为您提供一系列 IP。阅读documentation for NSHost

至于在 GUI 中显示,我推荐 Aaron Hillegass 的 Cocoa Programming for Mac OS X 的书,或者任何 Cocoa 初学者的书都应该教它。

【讨论】:

  • NSHost的地址顺序是否一致?我读过一些人说不是,但那只是在谈论普通地址,而不是地址。我从来没有机会使用 NSHost。
  • 嗯,数组确实保持顺序,而不是字典。但我真的不能说它有多可靠。
  • 好的。我的意思是,它总是走 IPv6、IPv4、链路本地、IPv4 环回、IPv6 环回吗?
  • 嗯.. 似乎如果您启用了 IPv6,它会首先显示,然后是 IPv4。否则我认为它遵循您的系统偏好 -> 网络接口列表的顺序。
【解决方案4】:

我刚刚写了这个,可能需要一些工作,但似乎在我的机器上运行良好......

- (NSString *)getLocalIPAddress
{
    NSArray *ipAddresses = [[NSHost currentHost] addresses];
    NSArray *sortedIPAddresses = [ipAddresses sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    numberFormatter.allowsFloats = NO;

    for (NSString *potentialIPAddress in sortedIPAddresses)
    {
        if ([potentialIPAddress isEqualToString:@"127.0.0.1"]) {
            continue;
        }

        NSArray *ipParts = [potentialIPAddress componentsSeparatedByString:@"."];

        BOOL isMatch = YES;

        for (NSString *ipPart in ipParts) {
            if (![numberFormatter numberFromString:ipPart]) {
                isMatch = NO;
                break;
            }
        }
        if (isMatch) {
            return potentialIPAddress;
        }
    }

    // No IP found
    return @"?.?.?.?";
}

【讨论】:

    【解决方案5】:

    我们可以对当前主机名使用hostWithName: 方法。这将仅返回单个本地 IPv4 和 IPv6 IP,我们可以轻松过滤。

    我们可以使用[[NSHost currentHost] name]获取当前系统主机名。

    +(NSString *)getLocalIPAddress{
        NSArray *ipAddresses = [[NSHost hostWithName:[[NSHost currentHost] name]] addresses];
        for (NSString *ipAddress in ipAddresses) {
            if ([ipAddress componentsSeparatedByString:@"."].count == 4) {
                return ipAddress;
            }
        }
        return @"Not Connected.";
    }
    

    因此,这将解决其他答案的 cmets 中提到的所有问题。此外,这比此处提到的其他解决方案的工作速度要快得多。

    【讨论】:

      猜你喜欢
      • 2011-05-30
      • 2020-01-10
      • 2011-06-28
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      • 2016-11-17
      • 2010-10-06
      • 1970-01-01
      相关资源
      最近更新 更多