首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 檢測網路連線狀態:InternetGetConnectedState API 完整封裝與最佳實踐

     編輯:關於C語言

前言:為何不直接 Ping?

常見做法 Ping 或嘗試連線特定網站,但:ICMP 可能被防火牆封鎖、目標網站可能暫時不可用、無法區分「區域網路連通」與「網際網路可達」。Windows 提供 wininet.dll!InternetGetConnectedState 直接查詢系統網路連線狀態旗標,無需發送封包,回應極快,且能區分「離線模式」、「Proxy」、「LAN」等連線類型。

API 簽名與參數

[DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool InternetGetConnectedState(out int lpdwFlags, int dwReserved);
  • lpdwFlags:輸出連線類型旗標組合(見下表)
  • dwReserved:保留,必須為 0
  • 返回值:true = 系統判定有可用連線,false = 完全離線

連線類型旗標

INTERNET_CONNECTION_MODEMINTERNET_CONNECTION_LANINTERNET_CONNECTION_PROXYINTERNET_CONNECTION_MODEM_BUSYINTERNET_RAS_INSTALLEDINTERNET_CONNECTION_OFFLINEINTERNET_CONNECTION_CONFIGURED
常數值含義
0x01撥號調變解調器連線
0x02區域網路連線
0x04透過 Proxy 連線
0x08調變解調器忙碌(無新連線)
0x10已安裝 RAS(遠端存取服務)
0x20離線模式
0x40已設定連線(不一定目前連通)

完整封裝類別

using System;
using System.Runtime.InteropServices;

public static class NetworkStatus
{
    [DllImport("wininet.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern bool InternetGetConnectedState(out int flags, int reserved);

    [Flags]
    public enum ConnectionType : int
    {
        Modem = 0x01,
        Lan = 0x02,
        Proxy = 0x04,
        ModemBusy = 0x08,
        RasInstalled = 0x10,
        Offline = 0x20,
        Configured = 0x40
    }

    public static bool IsConnected()
    {
        return InternetGetConnectedState(out _, 0);
    }

    public static bool IsConnected(out ConnectionType type)
    {
        int flags;
        bool result = InternetGetConnectedState(out flags, 0);
        type = (ConnectionType)flags;
        return result;
    }

    public static ConnectionType GetConnectionType()
    {
        InternetGetConnectedState(out int flags, 0);
        return (ConnectionType)flags;
    }

    public static string GetConnectionDescription()
    {
        var type = GetConnectionType();
        if (type == 0) return "離線 / 無連線";
        return type.ToString(); // FlagsAttribute 會自動組合顯示多標記
    }
}

使用範例

// 簡單檢查
if (NetworkStatus.IsConnected())
    Console.WriteLine("系統偵測到網路連線");
else
    Console.WriteLine("系統處於離線狀態");

// 詳細類型
if (NetworkStatus.IsConnected(out var type))
{
    Console.WriteLine($"連線類型:{type}");
    if (type.HasFlag(NetworkStatus.ConnectionType.Lan)) Console.WriteLine("→ 區域網路");
    if (type.HasFlag(NetworkStatus.ConnectionType.Proxy)) Console.WriteLine("→ 透過 Proxy");
    if (type.HasFlag(NetworkStatus.ConnectionType.Offline)) Console.WriteLine("→ 離線模式啟用");
}

// 取得描述字串
Console.WriteLine(NetworkStatus.GetConnectionDescription());

進階:結合 NetworkChange 事件即時監控

using System.Net.NetworkInformation;

NetworkChange.NetworkAvailabilityChanged += (s, e) =>
{
    Console.WriteLine($"網路可用性變更:{(e.IsAvailable ? "可用" : "不可用")}");
    if (e.IsAvailable)
        Console.WriteLine($"詳細:{NetworkStatus.GetConnectionDescription()}");
};

常見誤區與注意事項

  • 不代表真正能上網:僅表示系統網路介面啟用且有路由,實際能否連外仍需應用層驗證(HTTP 請求、DNS 解析)
  • VPN/虛擬網卡:可能被識別為 LAN,旗標組合較複雜
  • 管理員權限:呼叫無需管理員權限
  • 跨平台:僅限 Windows;.NET Core / 5+ 跨平台專案建議使用 System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable() 搭配實際連線測試

總結

InternetGetConnectedState 是 Windows 平台最輕量、最標準的「系統層網路狀態」查詢 API。封裝為靜態工具類後,可作為應用程式啟動檢查、離線模式切換、網路狀態圖示更新的基礎依據,**但不應作為業務層「能否呼叫 API」的唯一判斷**,最終仍需實際發送請求驗證。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved