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。コールバックを登録すると、ネットワークの状態が変化したときにシステムがコールバックを呼び出します。非効率ではありません。

Objective-C アプリに統合する方法を示すApple のサンプル コードReachabilityを参照してください。コードは iPhone 用ですが、Reachability.{m,h}OS X でも動作するはずです。

(Apple のサンプル コードSimpleReachを参照してください。5 年前のものですが、動作するはずです。)

于 2010-05-28T16:12:15.487 に答える