ローカルアプリケーションを作るときに、ネットワーク接続の有無をチェックすることがあります。どういうコードを書くでしょうか。
Windows 10 から Windows 11 への更新要件のひとつに「ネットワーク接続の有無」がありました。Windows 11 の更新チェックツールとして、有名どころ「ReadySunValley」がどんなコードを書いているのかチェックしてみました。
ReadySunValley 0.61.0 のコード
ReadySunValley のコードはこれ:
public bool IsInet() { try { using (var CheckInternet = new WebClient()) using (CheckInternet.OpenRead("http://clients3.google.com/generate_204")) { return true; } } catch { return false; } }
ReadySunValley 0.52.1 以前のコード
[System.Runtime.InteropServices.DllImport("wininet.dll")] private extern static bool InternetGetConnectedState(out int Description, int ReservedValue); public static bool isINet() { return InternetGetConnectedState(out _, 0); }
補足
コード修正されているもののリリースログを見る限りはバグなどの Issue が挙がってきて、ネットワーク接続の確認方法が修正されたというわけではなさそうです。
ただし「Improved Inet connectivity check」と書いてあるので、改善されたコードということになると思います。
新しいコードでは、WebClient を利用して以下の URL を開いています。この URL が開けたらネットワーク接続は可能ということみたいですが、これはどういった URL なのか:
調べてみたところだと、「The Chromium Projects - Network Portal Detection」が回答になりそうです。
空のページを HTTP Status 204 で返却することで知られている URL のようです。実際に wget で調べてみると、このとおり。
この修正は Android のネットワーク接続チェックと似たようなコードに修正したかったのだと思います。Android の場合は以下の URL で同じようなコードを確認しています:
Android Code Search で「generate_204」を検索すると実際のコードを確認できます。
ちなみに https でも 204 を返しました。
こんなテストコードもありました:
@Test public void testGetCaptivePortalServerUrl() throws Exception { String url = mCm.getCaptivePortalServerUrl(); assertEquals("http://connectivitycheck.gstatic.com/generate_204", url); }
というわけで、ネットワーク接続の有無のチェックで google 系は URL を叩いてステータスコードを確認してそうです。なので、それに倣ったネットワーク接続の有無のチェックに更新された、と考えることができそうです。
おまけ
(その昔よく利用した)dobon.net では NetworkInterface.GetIsNetworkAvailable
メソッドが紹介されています。
Refernece source でコードを確認してみると:
NetworkInterface クラスを取得して、どれかひとつでも if 条件をパスする状態だとネットワーク接続できる、というような感じです。
条件としては:
- ネットワークインターフェースが稼働していて (OperationalStatus.Up)
- ネットワークインターフェースの種類がトンネル接続でもループバック (!NetworkInterfaceType.Tunnel & Loopback) でもない
また、実際の接続を試してみる、というコードも記載されていますが、yahoo に接続してステータスを確認するような内容になっていて、最適化されたコードではなさそうです。