IP 주소변경 감시하는 방법




Mac OS X 에서 IP 주소를 감시하는 방법에 대해서 알아보도록 하겠습니다.


네트워크 관련해서 개발을 하다보면, IP Address 가 변경되었을 때 고려할 부분이 많습니다.

예를들어, 서버 모듈(소규모)의 경우 IP 주소가 변경된다면 서버의 역할을 할 수 없게 됩니다.

이런 경우에 내부적으로 IP 주소가 변경되었음을 감지하고, 서버를 Initialize 할 수도 있겠지요.

(물론 대부분 서버에는 이런 기능은 없습니다만...;)


모쪼록, IP 주소가 변경되었음을 감지하기 위해서 두 가지가 있습니다.

그런데 성격이 조금 다릅니다.


하나는 Target Host 를 지정하고, 그 호스트에 연결이 가능한지 아닌지 확인하는 방식입니다.

이 방식은 Target Host 를 필요로 합니다.

그렇기 때문에,,, 목적에 맞지 않는 것 같습니다.

더불어 Target Host 의 문제로 인하여, 연결이 불가능 한 경우도 있기 때문이죠.

본래 목적처럼 '내 PC 의 IP 주소 변경 유무'를 판단하기에도 무리가 있습니다.


두번째 방식은, 시스템의 설정값이 변경되었음을 감시하는 것입니다.

이 방식이 가장 적합하겠네요.


구현을 위해서 아래 Framework 를 사용합니다.


Framework
Declared in
SCDynamicStore.h 


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);

 

코드가 짧기 때문에, 설명은 생략하겠습니다.

각 함수에 대한 설명은, apple 개발자 페이지를 참고하시기 바랍니다.