4

我只需要在分配有效 IP 地址时发布通知。我曾尝试通过 SCReachability 进行轮询,但这似乎效率低下。

有什么建议么?这似乎应该很简单,但我已经努力了几个小时才能让任何工作正常进行。

4

2 回答 2

11

我知道这有点旧,但选择的答案并不理想。

SCReachability API 可用于了解特定主机何时可访问。如果您只想知道何时分配了有效 IP 地址(而不是到目标 IP 的可行路由),那么您应该查看 SCDynamicStore* API。这些功能允许您订阅系统的配置存储,以便在某些值更改时获得通知。因此,对于任何接口上的 IPv4 地址发生更改时的通知,您可以执行以下操作(为了便于阅读,删除了错误检查)

  SCDynamicStoreRef dynStore;

  SCDynamicStoreContext context = {0, NULL, NULL, NULL, NULL};

  dynStore = SCDynamicStoreCreate(kCFAllocatorDefault,
                                  CFBundleGetIdentifier(CFBundleGetMainBundle()),
                                  scCallback,
                                  &context);

    const CFStringRef keys[3] = {
        CFSTR("State:/Network/Interface/.*/IPv4")
    };
    CFArrayRef watchedKeys = CFArrayCreate(kCFAllocatorDefault,
                                         (const void **)keys,
                                         1,
                                         &kCFTypeArrayCallBacks);
    if (!SCDynamicStoreSetNotificationKeys(dynStore,
                                         NULL,
                                         watchedKeys)) 
  {
       CFRelease(watchedKeys);
        fprintf(stderr, "SCDynamicStoreSetNotificationKeys() failed: %s", SCErrorString(SCError()));
        CFRelease(dynStore);
        dynStore = NULL;

        return -1;
    }
    CFRelease(watchedKeys);

    rlSrc = SCDynamicStoreCreateRunLoopSource(kCFAllocatorDefault, dynStore, 0);
    CFRunLoopAddSource(CFRunLoopGetCurrent(), rlSrc, kCFRunLoopDefaultMode);
    CFRelease(rlSrc);

您将需要实现 scCallback 函数,只要有更改就会调用该函数。此外,您还需要在某处调用 CFRunLoopRun 以使代码运行。

于 2011-01-05T22:05:47.390 回答
1

您不必使用 进行轮询SCNetworkReachability。您注册回调,系统会在网络状态发生变化时调用回调。这不是低效的。

请参阅 Apple 的示例代码Reachability,它展示了如何将其集成到 Objective-C 应用程序中。该代码适用于 iPhone,但我认为Reachability.{m,h}应该适用于 OS X。

(请参阅 Apple 的示例代码SimpleReach。它已有五年历史,但应该可以工作。)

于 2010-05-28T16:12:15.487 回答