🔍 问题分析
1. 网关IP ≠ 热点IP
获取到的网关IP(Gateway IP)通常是指默认路由网关,不一定就是直接连接的WiFi热点的IP。例如:
WiFi热点 IP:192.168.1.1
网关 IP:192.168.1.1 (此时相同)
但在复杂网络中可能:
WiFi热点 IP:192.168.1.1
网关 IP:10.0.0.1 (被转发,网关在远端)
2. ARP缓存导致虚假ping成功
当WiFi断掉后,仍然能ping通的主要原因是 ARP缓存:
WiFi断掉时序:
时间1: WiFi连接 → ping 192.168.1.1 → 成功 → ARP缓存MAC地址
时间2: WiFi断开连接
时间3: ping 192.168.1.1 → 使用缓存的MAC地址 → 看似成功(但实际上没有发出去)
✅ 解决方案
方案1:清除ARP缓存后再ping(验证真实连接)
csharp
using System.Diagnostics;
/// <summary>
/// 清除ARP缓存并验证WiFi实际连接状态
/// </summary>
public static bool VerifyWiFiConnection(string targetIP)
{
try
{
// 步骤1:清除ARP缓存
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c ipconfig /all /flushdns && arp -d",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
using (Process process = Process.Start(psi))
{
process.WaitForExit();
}
Thread.Sleep(500); // 等待ARP缓存清除
// 步骤2:执行ping验证
ProcessStartInfo pingPsi = new ProcessStartInfo
{
FileName = "ping.exe",
Arguments = $"-n 1 {targetIP}",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
using (Process pingProcess = Process.Start(pingPsi))
{
string output = pingProcess.StandardOutput.ReadToEnd();
pingProcess.WaitForExit();
// 检查ping是否成功(Reply from 或 bytes=)
return output.Contains("Reply from") || output.Contains("bytes=");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return false;
}
}
方案2:使用NetworkInterface检测WiFi状态(更可靠)
csharp
/// <summary>
/// 检测WiFi是否真正连接(比ping更可靠)
/// </summary>
public static bool IsWiFiConnected()
{
try
{
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in interfaces)
{
// 检查是否为WiFi网卡
if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 &&
ni.OperationalStatus == OperationalStatus.Up)
{
// 关键:检查 OperationalStatus
// Up = 连接正常
// Down = 连接断开
IPInterfaceProperties ipProps = ni.GetIPProperties();
// 额外检查:是否有有效的IP地址
bool hasValidIP = ipProps.UnicastAddresses
.Any(x => x.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork &&
!IPAddress.IsLoopback(x.Address) &&
x.Address.ToString() != "0.0.0.0");
if (hasValidIP)
{
Console.WriteLine($"WiFi已连接: {ni.Name}");
Console.WriteLine($"状态: {ni.OperationalStatus}");
return true;
}
}
}
Console.WriteLine("WiFi未连接");
return false;
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return false;
}
}
方案3:通过WMI检测WiFi连接状态(最准确)
csharp
using System.Management;
/// <summary>
/// 通过WMI检测WiFi实际连接状态
/// </summary>
public static bool IsWiFiReallyConnected()
{
try
{
// 查询网络适配器状态
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled=true"
);
foreach (ManagementObject mo in searcher.Get())
{
string description = mo["Description"]?.ToString() ?? "";
if (description.Contains("Wireless") || description.Contains("WiFi"))
{
// 检查IP配置是否有效
object[] ipAddresses = mo["IPAddress"] as object[];
object[] subnetMasks = mo["IPSubnet"] as object[];
object[] gateways = mo["DefaultIPGateway"] as object[];
if (ipAddresses != null && ipAddresses.Length > 0 &&
gateways != null && gateways.Length > 0)
{
// 再查询网络适配器的物理状态
ManagementObjectSearcher adapterSearcher = new ManagementObjectSearcher(
$"SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionID='{mo["Description"]}'"
);
foreach (ManagementObject adapter in adapterSearcher.Get())
{
// NetEnabled = true 表示真正连接
bool isEnabled = (bool)adapter["NetEnabled"];
if (isEnabled)
{
Console.WriteLine($"WiFi真正已连接 (NetEnabled=true)");
return true;
}
}
}
}
}
Console.WriteLine("WiFi未连接");
return false;
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return false;
}
}
方案4:检测WiFi的SSID(最直接)
csharp
using System.Net.NetworkInformation;
using System.Diagnostics;
/// <summary>
/// 获取当前连接的WiFi SSID(最直接的方式)
/// </summary>
public static string GetConnectedWiFiSSID()
{
try
{
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = "netsh",
Arguments = "wlan show interfaces",
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true
};
using (Process process = Process.Start(psi))
{
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
// 解析输出,查找 "SSID"
string[] lines = output.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
foreach (string line in lines)
{
if (line.Contains("SSID"))
{
// 提取SSID值
string[] parts = line.Split(':');
if (parts.Length > 1)
{
string ssid = parts[1].Trim();
if (!string.IsNullOrEmpty(ssid) && ssid != "Not associated")
{
Console.WriteLine($"当前连接WiFi: {ssid}");
return ssid;
}
}
}
}
}
Console.WriteLine("未连接WiFi");
return null;
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return null;
}
}
📊 对比总结
| 检测方法 | 可靠性 | 速度 | 说明 |
|---|---|---|---|
| ping | ⭐ 低 | 快 | ARP缓存影响,不可靠 |
| NetworkInterface | ⭐⭐⭐ 高 | 快 | 检查OperationalStatus,较可靠 |
| WMI查询 | ⭐⭐⭐⭐ 很高 | 中 | 检查NetEnabled标志,最准确 |
| 获取SSID | ⭐⭐⭐⭐⭐ 最高 | 中 | 直接查询连接的热点名称,最直接 |
🎯 使用建议
csharp
// 完整的WiFi连接检测流程
public static bool CheckWiFiConnection()
{
// 第一步:检查网络接口状态(快速)
if (!IsWiFiConnected())
return false;
// 第二步:获取SSID确认(直接)
string ssid = GetConnectedWiFiSSID();
if (string.IsNullOrEmpty(ssid))
return false;
// 第三步:获取网关IP
string gatewayIP = GetWiFiGatewayIP();
Console.WriteLine($"连接的WiFi: {ssid}");
Console.WriteLine($"网关IP: {gatewayIP}");
return true;
}
推荐用方案2或方案4,不要单纯依赖ping命令。