2

gethostbyname() を使用してデバイスの IP を取得します。iOS5では問題なく動作しています。しかし iOS6 では、gethostbyname() によって返されるホスト値は NULL です。以下は、デバイスの現在のローカル IP を取得するための私のコードです。

// retun the host name
- (NSString *)hostname
{
    char baseHostName[256];
    int success = gethostname(baseHostName, 255);
    if (success != 0) return nil;
    baseHostName[255] = '\0';

#if !TARGET_IPHONE_SIMULATOR
    return [NSString stringWithFormat:@"%s.local", baseHostName];
#else
    return [NSString stringWithFormat:@"%s", baseHostName];
#endif
}

// return IP Address
- (NSString *)localIPAddress
{
    struct hostent *host = gethostbyname([[self hostname] UTF8String]);
    if (!host) {
        herror("resolv");
        return nil;
    }
    struct in_addr **list = (struct in_addr **)host->h_addr_list;
    return [NSString stringWithCString:inet_ntoa(*list[0]) encoding:NSUTF8StringEncoding];
}

シミュレーターは iOS5 と iOS6 の両方で動作することに注意してください。iOS6 デバイスのみが失敗しました。gethostbyname() の違いは何ですか? または、iOS6 でローカル IP を取得する他の解決策はありますか?

4

1 に答える 1

7

いくつかの問題が考えられます。

  • おそらくIPv6アドレスを持っています(gethostbyname()IPv4でのみ機能します)、
  • または、ホスト名から IP アドレスへの名前解決が正しく機能しません。

次のコードは、すべてのローカル アドレスを文字列の配列として返します。名前解決に依存せず、IPv4 アドレスと IPv6 アドレスの両方で動作します。

#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netdb.h>

// return all local IP addresses
- (NSArray *)localIPAddresses
{
    NSMutableArray *ipAddresses = [NSMutableArray array] ;

    struct ifaddrs *allInterfaces;

    // Get list of all interfaces on the local machine:
    if (getifaddrs(&allInterfaces) == 0) {
        struct ifaddrs *interface;

        // For each interface ...
        for (interface = allInterfaces; interface != NULL; interface = interface->ifa_next) {
            unsigned int flags = interface->ifa_flags;
            struct sockaddr *addr = interface->ifa_addr;

            // Check for running IPv4, IPv6 interfaces. Skip the loopback interface.
            if ((flags & (IFF_UP|IFF_RUNNING|IFF_LOOPBACK)) == (IFF_UP|IFF_RUNNING)) {
                if (addr->sa_family == AF_INET || addr->sa_family == AF_INET6) {

                    // Convert interface address to a human readable string:
                    char host[NI_MAXHOST];
                    getnameinfo(addr, addr->sa_len, host, sizeof(host), NULL, 0, NI_NUMERICHOST);

                    [ipAddresses addObject:[[NSString alloc] initWithUTF8String:host]];
                }
            }
        }

        freeifaddrs(allInterfaces);
    }
    return ipAddresses;
}
于 2012-12-29T17:13:37.767 に答える