Cách tốt nhất để kiểm tra kết nối Internet bằng .NET là gì?


237

Cách nhanh nhất và hiệu quả nhất để kiểm tra kết nối Internet trong .NET là gì?


6
Nếu người dùng có một sự hoàn hảo internet. Nếu người dùng có thể kết nối với internet. Để gửi một nhật ký email.
Mohit Deshpande

11
Chỉ cần gửi email. Nếu người dùng không được kết nối, bạn có thể sẽ nhận được một số ngoại lệ (dù sao bạn có thể sẽ phải xử lý).
Seth

15
Ngoài ra, lưu ý rằng không có cách nào để kiểm tra xem người dùng có được kết nối với internet hay không; tất cả những gì bạn có thể nói là nếu chúng được kết nối trong quá khứ . Giả sử bạn đã có một phương thức: "bool c = IsConnected (); if (c) {DoS Something ();}" - giữa cuộc gọi đến IsConnected và DoS Something, bộ định tuyến mạng không dây có thể đã được rút ra. IsConnected thực sự nên được gọi là WasRecentlyConnected.
Eric Lippert

Windows NLM APInên là tốt nhất cho việc này stackoverflow.com/questions/5405895/
Mahbubur Rahman

Câu trả lời:


292

Một cái gì đó như thế này sẽ làm việc.

System.Net.WebClient

public static bool CheckForInternetConnection()
{
    try
    {
        using (var client = new WebClient())
            using (client.OpenRead("http://google.com/generate_204")) 
                return true; 
    }
    catch
    {
        return false;
    }
}

18
Điều này có lẽ tốt hơn so với ping Google, bởi vì tôi nghĩ rằng chúng tôi không có gì đảm bảo rằng Google tiếp tục phản hồi với ping. Mặt khác, tôi không thể hình ảnh một thế giới nơi www.google.com không trả lại một số HTML :)
Daniel Vassallo

3
@Daniel: một mặt đúng, nhưng mặt khác, thực sự tải xuống trang web là một chút imo trên đầu
Leo

9
Dù bằng cách nào, không có lý do gì để kéo 4KB trở lại - chỉ cần sử dụng client.OpenRead (url) thay thế. Nếu nó không ném ngoại lệ thì nó đã có thể kết nối.
Josh M.

14
Điều đó thực sự không hiệu quả. Sử dụng điều đó làm cho chương trình của tôi bắt đầu hơn 1 phút nếu không có internet. Có lẽ là do cố gắng giải quyết DNS. Ping 8.8.8.8 (google dns) đã thay đổi thành 3 giây.
MadBoy

8
@DanielVassallo I cannot image a world where www.google.com does not return some HTMLở Trung Quốc chẳng hạn ...
Jérôme MEVEL

84

Hoàn toàn không có cách nào bạn có thể kiểm tra một cách đáng tin cậy nếu có kết nối internet hay không (tôi giả sử bạn có nghĩa là truy cập internet).

Tuy nhiên, bạn có thể yêu cầu các tài nguyên hầu như không bao giờ ngoại tuyến, như ping google.com hoặc một cái gì đó tương tự. Tôi nghĩ rằng điều này sẽ có hiệu quả.

try { 
    Ping myPing = new Ping();
    String host = "google.com";
    byte[] buffer = new byte[32];
    int timeout = 1000;
    PingOptions pingOptions = new PingOptions();
    PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
    return (reply.Status == IPStatus.Success);
}
catch (Exception) {
    return false;
}

24
+1 "Hoàn toàn không có cách nào bạn có thể kiểm tra một cách đáng tin cậy nếu có kết nối internet"
woz

6
Tất cả điều này là kiểm tra xem google có hoạt động không khi bạn ping nó. Nếu ngay sau khi ping thành công, internet của bạn bị sập thì sao? Không có điểm nào trong việc kiểm tra trước khi làm.
dbasnett

12
Và làm thế nào điều này mâu thuẫn với tuyên bố chính của câu trả lời của tôi?
Leo

10
Sử dụng "google.com" sẽ mất nhiều thời gian hơn vì nó cần được giải quyết. Thay vào đó, ping trực tiếp bằng IP sẽ nhanh hơn. Ping đến địa chỉ IP DNS công cộng của Google ( 8.8.8.8hoặc 8.8.4.4) hoạt động tốt với tôi.
Mangesh

8
Tôi muốn nhắc lại điểm rằng Beware - many schools and offices block the ping protocol.Nếu bạn đang sử dụng phương pháp này cho một ứng dụng sẽ được sử dụng bởi khách hàng, tôi sẽ khuyên bạn nên chống lại phương pháp kiểm tra internet này
user1

42

Thay vì kiểm tra, chỉ cần thực hiện hành động (yêu cầu web, thư, ftp, v.v.) và sẵn sàng cho yêu cầu thất bại, dù sao bạn cũng phải làm, ngay cả khi kiểm tra của bạn thành công.

Hãy xem xét những điều sau đây:

1 - check, and it is OK
2 - start to perform action 
3 - network goes down
4 - action fails
5 - lot of good your check did

Nếu mạng ngừng hoạt động, hành động của bạn sẽ thất bại nhanh như ping, v.v.

1 - start to perform action
2 - if the net is down(or goes down) the action will fail

9
Đúng! Chỉ cần làm điều đó - nhưng hãy chuẩn bị cho tất cả các kết quả.
Đại tá Panic

3
Hãy xem xét những điều sau: Bạn cần phải làm gì đó nếu mạng ngừng hoạt động trong khoảng thời gian x (ví dụ tracelog, thiết lập lại bộ định tuyến)
Abir

2
Không phải OP, nhưng lý do tôi muốn làm điều này là TRÁNH XÁC ĐỊNH 100 GIỜ THỨ HAI nếu không có kết nối Internet. Yêu cầu HTTP được thực hiện trên một luồng nền, do đó, luồng UI không bị chặn, nhưng ứng dụng của tôi không thể thoát cho đến khi luồng nền trả về từ yêu cầu HTTP và chấm dứt. Thay vì cố gắng tìm một số giá trị thời gian chờ "trung bình hạnh phúc", tôi chỉ muốn tránh yêu cầu hoàn toàn nếu tôi biết kết nối Internet bị hỏng.
Scott Smith

2
Quan điểm của tôi là chúng tôi không thể tính đến khi dịch vụ từ xa có thể khả dụng / không khả dụng. Ngoài ra, những gì về các trang web không phản hồi với ping?
dbasnett

Một trường hợp sử dụng khác là trình kiểm tra trực tuyến sẽ thông báo cho tôi ngay khi internet của tôi hoạt động trở lại
Ben Philipp

28

NetworkInterface.GetIsNetworkAvailablelà rất không đáng tin cậy. Chỉ cần có một số kết nối VMware hoặc LAN khác và nó sẽ trả về kết quả sai. Ngoài ra về Dns.GetHostEntryphương pháp tôi chỉ quan tâm đến việc liệu URL thử nghiệm có thể bị chặn trong môi trường nơi ứng dụng của tôi sẽ triển khai hay không.

Vì vậy, một cách khác tôi phát hiện ra là sử dụng InternetGetConnectedStatephương pháp. Mã của tôi là

[System.Runtime.InteropServices.DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

public static bool CheckNet()
{
     int desc;
     return InternetGetConnectedState(out desc, 0);         
}

Trong quá trình thử nghiệm, tôi thấy rằng InternetGetConnectedState đã trở lại đúng khi trình phát VMWare được cài đặt (internet bị ngắt kết nối). Phải vô hiệu hóa nó trong Bảng điều khiển \ Mạng và Internet \ Kết nối mạng (VMNet1 và VMNet8).
HockeyJ

Ok Justin Oringer. Mặc dù tôi đã kiểm tra nhưng phải xác minh lại
Kamran Shahid

2
Cách tiếp cận tốt nhất cho tôi, tôi vẫn kiểm tra kết nối dịch vụ của mình sau đó, sau đó bắt đầu các thói quen ... Tôi chỉ muốn tránh ngoại lệ.
Wagner Bertolini Junior

4
Mã này chỉ kiểm tra xem cáp mạng đã được cắm chưa.
HackerMan

14

Một thử nghiệm cho kết nối internet bằng cách ping Google:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success

7
Một mô tả đi cùng với câu trả lời này sẽ có ích cho nhiều người hơn là chỉ tác giả ban đầu của câu hỏi.
Boeckm

13
Coi chừng - nhiều trường học và văn phòng chặn giao thức ping. Ngớ ngẩn, tôi biết.
Đại tá Panic

Tôi không thể tìm thấy lớp ping. Liệu bạn có thể giúp mình không. Tôi đang làm việc trên UWP và các cách khác để thông tin mạng không hoạt động
iam.Carrot

12

Tôi không đồng ý với những người nêu rõ: "Điểm nào trong việc kiểm tra kết nối trước khi thực hiện một nhiệm vụ, vì ngay sau khi kiểm tra kết nối có thể bị mất". Chắc chắn có một mức độ không chắc chắn trong nhiều nhiệm vụ lập trình mà chúng tôi là nhà phát triển đảm nhận, nhưng việc giảm độ không chắc chắn xuống mức chấp nhận là một phần của thách thức.

Gần đây tôi gặp phải vấn đề này khi tạo một ứng dụng bao gồm tính năng ánh xạ được liên kết với máy chủ gạch trực tuyến. Chức năng này đã bị vô hiệu hóa khi thiếu kết nối internet.

Một số phản hồi trên trang này là rất tốt, tuy nhiên đã gây ra nhiều vấn đề về hiệu suất như treo, chủ yếu trong trường hợp không có kết nối.

Đây là giải pháp mà tôi đã kết thúc bằng cách sử dụng, với sự giúp đỡ của một số câu trả lời này và các đồng nghiệp của tôi:

         // Insert this where check is required, in my case program start
         ThreadPool.QueueUserWorkItem(CheckInternetConnectivity);
    }

    void CheckInternetConnectivity(object state)
    {
        if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
        {
            using (WebClient webClient = new WebClient())
            {
                webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
                webClient.Proxy = null;
                webClient.OpenReadCompleted += webClient_OpenReadCompleted;
                webClient.OpenReadAsync(new Uri("<url of choice here>"));
            }
        }
    }

    volatile bool internetAvailable = false; // boolean used elsewhere in code

    void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            internetAvailable = true;
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
            {
                // UI changes made here
            }));
        }
    }

11

Tôi đã thấy tất cả các tùy chọn được liệt kê ở trên và tùy chọn khả thi duy nhất để kiểm tra khô héo internet có sẵn hay không là tùy chọn "Ping". Nhập [DllImport("Wininet.dll")]System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() Hoặc bất kỳ biến thể nào khác của NetworkInterface lớp không hoạt động tốt trong việc phát hiện tính khả dụng của mạng. Các phương thức này chỉ kiểm tra xem cáp mạng có được cắm hay không.

"Tùy chọn Ping"

if(Kết nối có sẵn) trả về true

if(Kết nối không khả dụng và cáp mạng được cắm) trả về false

if(Cáp mạng không được cắm) Throws an exception

NetworkInterface

if(Internet có sẵn) Trả về True

if(Internet không khả dụng và Cáp mạng đã được cắm) Trả về True

if(Cáp mạng không được cắm) trả về false

[DLLImport ("Wininet.dll")]

if(Internet có sẵn) Trả về True

if(Internet không khả dụng và Cáp mạng đã được cắm) Trả về True

if(Cáp mạng không được cắm) trả về false

Vì vậy, trong trường hợp [DllImport("Wininet.dll")]NetworkInterface Không có cách nào để biết nếu kết nối internet có sẵn.


Điều này không đúng, tôi đã nhập Wininet.dll, cắm cáp mạng và có kết quả chính xác cho tình huống internet không khả dụng.
Waldemar Gałęzinowski

8

Không giải quyết vấn đề mạng đi xuống giữa việc kiểm tra và chạy mã của bạn nhưng khá đáng tin cậy

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    {
        // however, this will include all adapters -- filter by opstatus and activity
        NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
        return (from face in interfaces
                where face.OperationalStatus == OperationalStatus.Up
                where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
                select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
    }

    return false;
}

Ý tưởng tuyệt vời, nhưng như bạn nói có thể không hoàn hảo. Bạn có thể lưu trữ các byte được gửi / nhận cũng như để kiểm tra trong tương lai. Vẫn không hoàn hảo mặc dù.
Todd

Mã này không hoạt động, xin vui lòng sửa. Nó chỉ kiểm tra xem cáp mạng có được cắm hay không.
HackerMan

5

Ping Google.com giới thiệu một phụ thuộc độ phân giải DNS. Pinging 8.8.8.8 vẫn ổn nhưng Google cách tôi vài bước. Tất cả những gì tôi cần làm là ping thứ gần nhất với tôi trên internet.

Tôi có thể sử dụng tính năng TTL của Ping để ping hop # 1, sau đó hop # 2, v.v., cho đến khi tôi nhận được câu trả lời từ một địa chỉ có thể định tuyến; nếu nút đó nằm trên một địa chỉ có thể định tuyến thì nó nằm trên internet. Đối với hầu hết chúng ta, hop # 1 sẽ là cổng / bộ định tuyến cục bộ của chúng tôi và hop # 2 sẽ là điểm đầu tiên ở phía bên kia của kết nối sợi quang của chúng tôi hoặc bất cứ điều gì.

Mã này hoạt động với tôi và phản hồi nhanh hơn một số đề xuất khác trong chủ đề này bởi vì nó đang ping bất cứ thứ gì gần tôi nhất trên internet.

using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Diagnostics;

internal static bool ConnectedToInternet()
{
    const int maxHops = 30;
    const string someFarAwayIpAddress = "8.8.8.8";

    // Keep pinging further along the line from here to google 
    // until we find a response that is from a routable address
    for (int ttl = 1; ttl <= maxHops; ttl++)
    {
        Ping pinger = new Ping();
        PingOptions options = new PingOptions(ttl, true);
        byte[] buffer = new byte[32];
        PingReply reply = null;
        try
        {
            reply = pinger.Send(someFarAwayIpAddress, 10000, buffer, options);
        }
        catch (System.Net.NetworkInformation.PingException pingex)
        {
            Debug.Print("Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: " + pingex.Message);
            return false;
        }

        System.Diagnostics.Debug.Print("Hop #" + ttl.ToString() + " is " + (reply.Address == null ? "null" : reply.Address.ToString()) + ", " + reply.Status.ToString());

        if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
        {
            Debug.Print("Hop #" + ttl.ToString() + " is " + reply.Status.ToString() + ", hence we are not connected.");
            return false;
        }

        if (IsRoutableAddress(reply.Address))
        {
            System.Diagnostics.Debug.Print("That's routable so you must be connected to the internet.");
            return true;
        }
    }

    return false;
}

private static bool IsRoutableAddress(IPAddress addr)
{
    if (addr == null)
    {
        return false;
    }
    else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
    {
        return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
    }
    else // IPv4
    {
        byte[] bytes = addr.GetAddressBytes();
        if (bytes[0] == 10)
        {   // Class A network
            return false;
        }
        else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
        {   // Class B network
            return false;
        }
        else if (bytes[0] == 192 && bytes[1] == 168)
        {   // Class C network
            return false;
        }
        else
        {   // None of the above, so must be routable
            return true;
        }
    }
}

4

Đây là cách nó được thực hiện trong Android.

Để chứng minh khái niệm, tôi đã dịch mã này sang C #:

var request = (HttpWebRequest)WebRequest.Create("http://g.cn/generate_204");
request.UserAgent = "Android";
request.KeepAlive = false;
request.Timeout = 1500;

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.ContentLength == 0 && response.StatusCode == HttpStatusCode.NoContent)
    {
        //Connection to internet available
    }
    else
    {
        //Connection to internet not available
    }
}

3
private bool ping()
{
    System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
    System.Net.NetworkInformation.PingReply reply = pingSender.Send(address);
    if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
    {                
        return true;
    }
    else
    {                
        return false;
    }
}

2

Một tùy chọn khác là API Trình quản lý danh sách mạng có sẵn cho Vista và Windows 7. Bài viết MSDN tại đây . Trong bài viết là một liên kết để tải xuống các mẫu mã cho phép bạn làm điều này:

AppNetworkListUser nlmUser = new AppNetworkListUser();
Console.WriteLine("Is the machine connected to internet? " + nlmUser.NLM.IsConnectedToInternet.ToString());

Đảm bảo thêm một tham chiếu đến Thư viện loại 1.0 Danh sách mạng từ tab COM ... sẽ hiển thị dưới dạng NETWORKLIST.


7
eeeeww. Sử dụng địa ngục COM trong .NET?
jgauffin

@jgauffin Bạn có thể giải thích tại sao người ta nên tránh COM trong .NET không? So với các giải pháp khác mà tôi tìm thấy, giải pháp COM dường như hoạt động khá tốt.
inexcitus

2

Cố gắng tránh kiểm tra các kết nối bằng cách bắt ngoại lệ. bởi vì chúng tôi thực sự mong đợi rằng đôi khi chúng tôi có thể mất kết nối mạng.

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline

1
NetworkInterface đến từ đâu? EDIT: Tôi tìm thấy nó: System.Net.NetworkIn
information


1

Cá nhân tôi thấy câu trả lời của Anton và moffeltje là tốt nhất, nhưng tôi đã thêm một kiểm tra để loại trừ các mạng ảo được thiết lập bởi VMWare và những người khác.

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) return false;

    // however, this will include all adapters -- filter by opstatus and activity
    NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    return (from face in interfaces
            where face.OperationalStatus == OperationalStatus.Up
            where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
            where (!(face.Name.ToLower().Contains("virtual") || face.Description.ToLower().Contains("virtual")))
            select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
}

FYI từ các tài liệu GetIsNetworkAv Available (): Kết nối mạng được coi là khả dụng nếu bất kỳ giao diện mạng nào được đánh dấu "lên" và không phải là giao diện loopback hoặc đường hầm. Tôi không biết liệu ảo sẽ luôn ở trong tên hoặc mô tả của khu vực không gian. Đó có phải là tiêu chuẩn?
Mike Cheel

1
bool bb = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();

if (bb == true)
    MessageBox.Show("Internet connections are available");
else
    MessageBox.Show("Internet connections are not available");

1
Bạn có thể thêm thông tin liên quan đến tốc độ này và làm thế nào điều này tốt hơn các giải pháp khác được đăng. Điều này sẽ giúp câu trả lời của bạn trong việc giải quyết đầy đủ câu hỏi.
Ren

8
Vấn đề với tùy chọn này là bbvẫn đúng ngay cả khi mạng không được kết nối với internet.
Halfpastfour.am

2
Mặc dù sự thật là điều này không trả lời trực tiếp câu hỏi, tôi nghĩ rằng vẫn hữu ích khi sử dụng GetIsNetworkAv Available như một kiểm tra trước khi thử ping Google, v.v.
Ben Hughes

3
Mã này không cho biết Kết nối Internet có khả dụng hay không. Nếu bạn cắm cáp mạng mà không có internet, nó sẽ trở về đúng.
HackerMan

1

Phiên bản đa luồng của ping:

  using System;
  using System.Collections.Generic;
  using System.Diagnostics;
  using System.Net.NetworkInformation;
  using System.Threading;


  namespace OnlineCheck
  {
      class Program
      {

          static bool isOnline = false;

          static void Main(string[] args)
          {
              List<string> ipList = new List<string> {
                  "1.1.1.1", // Bad ip
                  "2.2.2.2",
                  "4.2.2.2",
                  "8.8.8.8",
                  "9.9.9.9",
                  "208.67.222.222",
                  "139.130.4.5"
                  };

              int timeOut = 1000 * 5; // Seconds


              List<Thread> threadList = new List<Thread>();

              foreach (string ip in ipList)
              {

                  Thread threadTest = new Thread(() => IsOnline(ip));
                  threadList.Add(threadTest);
                  threadTest.Start();
              }

              Stopwatch stopwatch = Stopwatch.StartNew();

              while (!isOnline && stopwatch.ElapsedMilliseconds <= timeOut)
              {
                   Thread.Sleep(10); // Cooldown the CPU
              }

              foreach (Thread thread in threadList)
              { 
                  thread.Abort(); // We love threads, don't we?
              }


              Console.WriteLine("Am I online: " + isOnline.ToYesNo());
              Console.ReadKey();
          }

          static bool Ping(string host, int timeout = 3000, int buffer = 32)
          {
              bool result = false;

              try
              {
                  Ping ping = new Ping();                
                  byte[] byteBuffer = new byte[buffer];                
                  PingOptions options = new PingOptions();
                  PingReply reply = ping.Send(host, timeout, byteBuffer, options);
                  result = (reply.Status == IPStatus.Success);
              }
              catch (Exception ex)
              {

              }

              return result;
          }

          static void IsOnline(string host)
          {
              isOnline =  Ping(host) || isOnline;
          }
      }

      public static class BooleanExtensions
      {
          public static string ToYesNo(this bool value)
          {
              return value ? "Yes" : "No";
          }
      }
  }

0

Tôi sẽ không nghĩ rằng điều đó là không thể, chỉ là không đơn giản.

Tôi đã xây dựng một cái gì đó như thế này, và vâng, nó không hoàn hảo, nhưng bước đầu tiên là điều cần thiết: kiểm tra xem có kết nối mạng nào không. Windows Api không làm tốt công việc, vậy tại sao không làm tốt hơn?

bool NetworkIsAvailable()
{
    var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    foreach (var item in all)
    {
        if (item.NetworkInterfaceType == NetworkInterfaceType.Loopback)
            continue;
        if (item.Name.ToLower().Contains("virtual") || item.Description.ToLower().Contains("virtual"))
            continue; //Exclude virtual networks set up by VMWare and others
        if (item.OperationalStatus == OperationalStatus.Up)
        {
            return true;
        }
    }

    return false;
}

Điều này khá đơn giản, nhưng nó thực sự giúp cải thiện chất lượng kiểm tra, đặc biệt là khi bạn muốn kiểm tra các cấu hình proxy khác nhau.

Vì thế:

  • Kiểm tra xem có kết nối mạng hay không (làm cho điều này thực sự tốt, thậm chí có thể có các bản ghi được gửi lại cho nhà phát triển khi có kết quả dương tính giả để cải thiện chức năng NetworkIsAv Available)
  • Ping Ping
  • (Chuyển qua các cấu hình Proxy với HTTP Pings trên mỗi)

1
@hackerman đây là bước đầu tiên không rõ ràng. Các lập trình viên có thể tạo ra một ping nhanh đến máy chủ của riêng họ nếu nó trả về đúng, như một bước thứ hai. Điều quan trọng, điều này cung cấp một giải pháp thay thế cho phương pháp api windows bị lỗi. Phần còn lại là chi tiết.
Todd

3
Làm sai lệch. Nếu không có giao diện mạng, chắc chắn không có internet. Có thể cập nhật ui ngay lập tức mà không bị trì hoãn, không kiểm tra thêm trên các máy chủ khác.
Todd

0
public static bool Isconnected = false;

public static bool CheckForInternetConnection()
{
    try
    {
        Ping myPing = new Ping();
        String host = "google.com";
        byte[] buffer = new byte[32];
        int timeout = 1000;
        PingOptions pingOptions = new PingOptions();
        PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
        if (reply.Status == IPStatus.Success)
        {
            return true;
        }
        else if (reply.Status == IPStatus.TimedOut)
        {
            return Isconnected;
        }
        else
        {
            return false;
        }
    }
    catch (Exception)
    {
        return false;
    }
}

public static void CheckConnection()
{
    if (CheckForInternetConnection())
    {
        Isconnected = true;
    }
    else
    {
        Isconnected = false;
    }
}

Hãy bình luận câu trả lời của bạn. Câu trả lời chỉ có mã không được phép.
ganchito55

Đó là khá tự giải thích, chính sách vì lợi ích của chính sách?
cuộn

0

Sử dụng NetworkMonitor để theo dõi trạng thái mạng và kết nối internet.

Mẫu vật:

namespace AmRoNetworkMonitor.Demo
{
    using System;

    internal class Program
    {
        private static void Main()
        {
            NetworkMonitor.StateChanged += NetworkMonitor_StateChanged;
            NetworkMonitor.StartMonitor();

            Console.WriteLine("Press any key to stop monitoring.");
            Console.ReadKey();
            NetworkMonitor.StopMonitor();

            Console.WriteLine("Press any key to close program.");
            Console.ReadKey();
        }

        private static void NetworkMonitor_StateChanged(object sender, StateChangeEventArgs e)
        {
            Console.WriteLine(e.IsAvailable ? "Is Available" : "Is Not Available");
        }
    }
}

Ý tưởng hay, nhưng kiểm tra tính khả dụng của mạng, không phải tính khả dụng của internet
John Demetriou

Lớp này cũng kiểm tra tính khả dụng của Internet: SourceCode

Vấn đề là, tôi đã thử nó, nhưng nó chỉ bắn nếu không có mạng
John Demetriou

0

Giới thiệu

Trong một số trường hợp, bạn cần kiểm tra xem internet có khả dụng hay không sử dụng mã C # trong các ứng dụng Windows. Có thể tải xuống hoặc tải lên một tệp bằng internet ở dạng cửa sổ hoặc để lấy một số dữ liệu từ cơ sở dữ liệu ở vị trí xa, trong những tình huống này, việc kiểm tra internet là bắt buộc.

Có một số cách để kiểm tra tính khả dụng của internet bằng C # từ mã phía sau. Tất cả các cách như vậy được giải thích ở đây bao gồm cả những hạn chế của họ.

  1. InternetGetConnectedState (wininet)

API 'wininet' có thể được sử dụng để kiểm tra hệ thống cục bộ có kết nối internet hoạt động hay không. Không gian tên được sử dụng cho điều này là 'System.R.78.InteropService' và nhập dll 'wininet.dll' bằng cách sử dụng DLLImport. Sau đó, tạo một biến boolean với extern static với tên hàm InternetGetConnectedState với hai tham số mô tả và reservedValue như trong ví dụ.

Lưu ý: Công cụ sửa đổi bên ngoài được sử dụng để khai báo một phương thức được triển khai bên ngoài. Một cách sử dụng phổ biến của công cụ sửa đổi bên ngoài là với thuộc tính DLLImport khi bạn đang sử dụng các dịch vụ Interop để gọi vào mã không được quản lý. Trong trường hợp này, phương thức cũng phải được khai báo là tĩnh.

Tiếp theo, tạo một phương thức với tên 'IsINETAv Available' là boolean. Hàm trên sẽ được sử dụng trong phương thức này trả về trạng thái internet của hệ thống cục bộ

[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(out int description, int reservedValue);
public static bool IsInternetAvailable()
{
    try
    {
        int description;
        return InternetGetConnectedState(out description, 0);
    }
    catch (Exception ex)
    {
        return false;
    }
}
  1. GetIsNetworkAv Available

Ví dụ sau sử dụng phương thức GetIsNetworkAv Available để xác định xem có kết nối mạng không.

if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
{
    System.Windows.MessageBox.Show("This computer is connected to the internet");
}
else
{
    System.Windows.MessageBox.Show("This computer is not connected to the internet");
}

Lưu ý (Theo MSDN): Kết nối mạng được coi là khả dụng nếu bất kỳ giao diện mạng nào được đánh dấu "lên" và không phải là giao diện loopback hoặc đường hầm.

Có nhiều trường hợp thiết bị hoặc máy tính không được kết nối với mạng hữu ích nhưng vẫn được coi là khả dụng và GetIsNetworkAv Available sẽ trở lại đúng. Ví dụ: nếu thiết bị chạy ứng dụng được kết nối với mạng không dây yêu cầu proxy, nhưng proxy không được đặt, GetIsNetworkAv Available sẽ trả về đúng. Một ví dụ khác khi GetIsNetworkAv Available sẽ trở lại đúng là nếu ứng dụng đang chạy trên máy tính được kết nối với một trung tâm hoặc bộ định tuyến nơi trung tâm hoặc bộ định tuyến bị mất kết nối ngược dòng.

  1. Ping tên máy chủ trên mạng

Các lớp Ping và PingReply cho phép một ứng dụng xác định xem một máy tính từ xa có thể truy cập qua mạng hay không bằng cách nhận phản hồi từ máy chủ. Các lớp này có sẵn trong không gian tên System.Net.NetworkIn information. Ví dụ sau đây cho thấy cách ping máy chủ.

protected bool CheckConnectivity(string ipAddress)
{
    bool connectionExists = false;
    try
    {
        System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
        System.Net.NetworkInformation.PingOptions options = new System.Net.NetworkInformation.PingOptions();
        options.DontFragment = true;
        if (!string.IsNullOrEmpty(ipAddress))
        {
            System.Net.NetworkInformation.PingReply reply = pingSender.Send(ipAddress);
            connectionExists = reply.Status == 
System.Net.NetworkInformation.IPStatus.Success ? true : false;
        }
    }
    catch (PingException ex)
    {
        Logger.LogException(ex.Message, ex);
    }
    return connectionExists;
}

Lưu ý (Theo MSDN): Các ứng dụng sử dụng lớp Ping để phát hiện xem máy tính từ xa có thể truy cập được hay không. Cấu trúc liên kết mạng có thể xác định xem Ping có thể liên hệ thành công với máy chủ từ xa không. Sự hiện diện và cấu hình của proxy, thiết bị dịch địa chỉ mạng (NAT) hoặc tường lửa có thể ngăn Ping thành công. Ping thành công chỉ ra rằng máy chủ từ xa có thể được truy cập trên mạng; sự hiện diện của các dịch vụ cấp cao hơn (như máy chủ Web) trên máy chủ từ xa không được đảm bảo.

Bình luận / Gợi ý được mời. Chúc mừng mã hóa ......!


-1

Đối với ứng dụng của tôi, chúng tôi cũng kiểm tra bằng cách tải xuống tệp nhỏ.

string remoteUri = "https://www.microsoft.com/favicon.ico"

WebClient myWebClient = new WebClient();

try
{
    byte[] myDataBuffer = myWebClient.DownloadData (remoteUri);
    if(myDataBuffer.length > 0) // Or add more validate. eg. checksum
    {
        return true;
    }
}
catch
{
    return false;
}

Cũng thế. Một số ISP có thể sử dụng máy chủ giữa để lưu trữ tệp. Thêm tham số không sử dụng ngẫu nhiên, ví dụ. https://www.microsoft.com/favicon.ico?req=random_number Có thể ngăn chặn bộ đệm.


-1

Tôi gặp sự cố với các phương thức đó trên Bộ định tuyến / modem 3g của mình, vì nếu internet bị ngắt kết nối, bộ định tuyến sẽ chuyển hướng trang đến trang phản hồi của nó, vì vậy bạn vẫn nhận được hơi nước và mã của bạn nghĩ rằng có internet. Táo (hoặc những người khác) có trang phân tích điểm nóng luôn trả về một phản hồi nhất định. Mẫu sau trả về phản hồi "Thành công". Vì vậy, bạn sẽ chắc chắn chính xác rằng bạn có thể kết nối internet và nhận được phản hồi thực sự!

public static bool CheckForInternetConnection()
{
    try
    {       
        using (var webClient = new WebClient())
        using (var stream = webClient.OpenRead("http://captive.apple.com/hotspot-detect.html"))
        {
            if (stream != null)
            {
                //return true;
                stream.ReadTimeout = 1000;
                using (var reader = new StreamReader(stream, Encoding.UTF8, false))
                {
                    string line;
                    while ((line = reader.ReadLine()) != null)
                    {
                        if (line == "<HTML><HEAD><TITLE>Success</TITLE></HEAD><BODY>Success</BODY></HTML>")
                        {
                            return true;
                        }
                        Console.WriteLine(line);
                    }
                }

            }
            return false;
        }
    }
    catch
    {

    }
    return false;
}

-2

Tôi có ba bài kiểm tra cho một kết nối Internet.

  • Tham khảo System.NetSystem.Net.Sockets
  • Thêm các chức năng kiểm tra sau:

Kiểm tra 1

public bool IsOnlineTest1()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

Kiểm tra 2

public bool IsOnlineTest2()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

Bài kiểm tra 3

public bool IsOnlineTest3()
{
    System.Net.WebRequest req = System.Net.WebRequest.Create("https://www.google.com");
    System.Net.WebResponse resp = default(System.Net.WebResponse);
    try
    {
        resp = req.GetResponse();
        resp.Close();
        req = null;
        return true;
    }
    catch (Exception ex)
    {
        req = null;
        return false;
    }
}

Thực hiện các bài kiểm tra

Nếu bạn thực hiện một Dictionarysố StringBooleangọi CheckList, bạn có thể thêm các kết quả của mỗi bài kiểm tra để CheckList.

Bây giờ, lặp lại qua từng KeyValuePairbằng cách sử dụng một for...eachvòng lặp.

Nếu CheckListcó chứa một Valuesố true, sau đó bạn biết có một kết nối Internet.


-4
public static bool HasConnection()
{
    try
    {
        System.Net.IPHostEntry i = System.Net.Dns.GetHostEntry("www.google.com");
        return true;
    }
    catch
    {
        return false;
    }
}

Nó hoạt động


46
Nếu bạn có IP của google trong bộ đệm DNS, nó sẽ không gửi yêu cầu DNS, vì vậy nó có thể trả về đúng ngay cả khi bạn không được kết nối
Thomas Levesque
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.