IPアドレスが変わった事を知る

ある特定のIPアドレスでbind()するようなコードを書いていると、DHCPなどによりIPアドレスが変更されたというイベントを取得したいと思う場合があります。 IPHLPAPIのNotifyAddrChange()関数を利用すると、IPアドレスの変更を取得できます。

サンプルコード

NotifyAddrChange()を使ったサンプルコードを以下に示します。


#include <stdio.h>
#include <windows.h>

#include <winsock2.h>
#include <iphlpapi.h>

int
main()
{
 OVERLAPPED overlap;
 DWORD ret;

 HANDLE hand = WSACreateEvent();
 overlap.hEvent = WSACreateEvent();

 ret = NotifyAddrChange(&hand, &overlap);

 if (ret != NO_ERROR) {
   if (WSAGetLastError() != WSA_IO_PENDING) {
     printf("NotifyAddrChange error...%d\n", WSAGetLastError());
     return 1;
   }
 }

 if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0) {
   printf("IP Address table changed.\n");
 }

 return 0;
}

サンプルコード実行例

上記コードをコンパイルして出来たものを実行すると、以下のようになります。 ただし、このコードはIPアドレスが変更されないと実行が進まないので、コード実行中に「ipconfig /release」などを行ってIPアドレスを変更してみてください。


C:> a.exe
IP Address table changed.

サンプルコード2

NofityAddrChange()関数の引数を両方ともNULLにすると、NofityAddrChange()はIPアドレステーブルに変更が発生するまでブロックします。 単純にIPアドレスの変更を待つだけのスレッドを作りたい場合には、この方法が有効であると思われます。

以下にNotifyAddrChange(NULL,NULL)のサンプルを示します。 実行結果は1つめのサンプルと同様になるため、割愛させて頂きたいと思います。


#include <stdio.h>

#include <winsock2.h>
#include <iphlpapi.h>

int
main()
{
 DWORD ret;

 ret = NotifyAddrChange(NULL, NULL);

 if (ret != NO_ERROR) {
   if (WSAGetLastError() != WSA_IO_PENDING) {
     printf("NotifyAddrChange error...%d\n", WSAGetLastError());
     return 1;
   }
 }

 printf("IP Address table changed.\n");

 return 0;
}

IPv6基礎検定

YouTubeチャンネルやってます!