Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C#

วิธีตรวจสอบการเชื่อมต่ออินเทอร์เน็ตใน C#

การเช็ค Internet Connectivity ใน C# มีหลายวิธี ขึ้นอยู่กับความแม่นยำและ Use Case

วิธีที่ 1: HttpClient / WebClient (Real Connectivity Test - แนะนำ)

ทดสอบจริงโดย Request ไปยัง Endpoint ที่เชื่อถือได้

using System;
using System.Net.Http;
using System.Threading.Tasks;

public static class ConnectivityChecker
{
    private static readonly HttpClient _httpClient = new HttpClient
    {
        Timeout = TimeSpan.FromSeconds(5)
    };
    
    // Google Generate 204 - Endpoint มาตรฐานสำหรับ Captive Portal Detection
    private const string TestUrl = "https://www.google.com/generate_204";
    
    public static async Task IsConnectedAsync()
    {
        try
        {
            using var response = await _httpClient.GetAsync(TestUrl, HttpCompletionOption.ResponseHeadersRead);
            return response.StatusCode == System.Net.HttpStatusCode.NoContent; // 204
        }
        catch
        {
            return false;
        }
    }
    
    // Synchronous Version (สำหรับ Legacy/Console)
    public static bool IsConnected()
    {
        try
        {
            using var client = new System.Net.WebClient();
            using var stream = client.OpenRead(TestUrl);
            return true;
        }
        catch
        {
            return false;
        }
    }
}

// ใช้งาน
static async Task Main()
{
    bool connected = await ConnectivityChecker.IsConnectedAsync();
    Console.WriteLine($"Internet: {(connected ? "Connected" : "Disconnected")}");
}

วิธีที่ 2: NetworkInterface (Local Network Only - ไม่ใช่ Internet)

using System.Net.NetworkInformation;

public static bool IsNetworkAvailable()
{
    return NetworkInterface.GetIsNetworkAvailable();
}

// รายละเอียด
public static void PrintNetworkStatus()
{
    if (!NetworkInterface.GetIsNetworkAvailable())
    {
        Console.WriteLine("No Network Interface Up");
        return;
    }
    
    foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (ni.OperationalStatus == OperationalStatus.Up)
        {
            Console.WriteLine($"Interface: {ni.Name} ({ni.NetworkInterfaceType})");
            Console.WriteLine($"  Speed: {ni.Speed / 1_000_000} Mbps");
            Console.WriteLine($"  IPv4: {ni.GetIPProperties().UnicastAddresses.FirstOrDefault(a => a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)?.Address}");
        }
    }
}

⚠️ NetworkInterface.GetIsNetworkAvailable() คืน True หากมี NIC ใด NIC หนึ่ง Up แม้จะไม่มี Internet (เช่น Connected to LAN Only)

วิธีที่ 3: Ping (ICMP - ไม่เสมอไปที่ทำงาน)

public static bool PingHost(string host = "8.8.8.8", int timeout = 3000)
{
    try
    {
        using var ping = new Ping();
        PingReply reply = ping.Send(host, timeout);
        return reply.Status == IPStatus.Success;
    }
    catch
    {
        return false;
    }
}

⚠️ หลาย Network/Firewall Block ICMP → False Negative

วิธีที่ 4: Continuous Monitoring (Retry Loop)

public static async Task WaitForInternetAsync(TimeSpan? timeout = null, TimeSpan? retryInterval = null)
{
    var cts = timeout.HasValue ? new CancellationTokenSource(timeout.Value) : new CancellationTokenSource();
    var interval = retryInterval ?? TimeSpan.FromSeconds(5);
    
    while (!cts.Token.IsCancellationRequested)
    {
        if (await IsConnectedAsync())
        {
            Console.WriteLine("Internet connected!");
            return;
        }
        
        Console.WriteLine("No internet, retrying...");
        try { await Task.Delay(interval, cts.Token); }
        catch (OperationCanceledException) { break; }
    }
    
    throw new TimeoutException("Timed out waiting for internet connection");
}

Best Practices

  • ใช้ HTTP/HTTPS Endpoint (Port 80/443) แทน Ping (ICMP) เพราะ Firewall มัก Block ICMP
  • Endpoint ควรเป็น Generate 204 (No Content, Fast, Standard)
  • ตั้ง Timeout สั้น (3-5 วินาที) ป้องกัน Hang
  • ใช้ HttpCompletionOption.ResponseHeadersRead ไม่ต้อง Download Body
  • Handle TaskCanceledException (Timeout) และ HttpRequestException
  • ใน Mobile/Xamarin/MAUI: ใช้ Connectivity Plugin (Xamarin.Essentials / MAUI Essentials)

ใน ASP.NET Core Health Checks

// Startup.cs
services.AddHealthChecks()
    .AddUrlGroup(new Uri("https://www.google.com/generate_204"), "internet-check", 
        timeout: TimeSpan.FromSeconds(5));

// หรือ Custom Health Check
public class InternetHealthCheck : IHealthCheck
{
    public async Task CheckHealthAsync(HealthCheckContext context, CancellationToken ct = default)
    {
        bool connected = await ConnectivityChecker.IsConnectedAsync();
        return connected ? HealthCheckResult.Healthy() : HealthCheckResult.Unhealthy("No internet");
    }
}