วิธีที่ดีที่สุดในการตรวจสอบการเชื่อมต่ออินเทอร์เน็ตโดยใช้. NET คืออะไร?


237

วิธีที่เร็วและมีประสิทธิภาพที่สุดในการตรวจสอบการเชื่อมต่ออินเทอร์เน็ตใน. NET คืออะไร?


6
หากผู้ใช้มีอินเทอร์เน็ต conecction หากผู้ใช้สามารถเชื่อมต่ออินเทอร์เน็ต เพื่อที่จะส่งบันทึกอีเมล
Mohit Deshpande

11
เพียงส่งอีเมล หากผู้ใช้ไม่ได้เชื่อมต่อคุณอาจได้รับข้อยกเว้นบางประการ (ซึ่งคุณอาจต้องจัดการเอง)
เซท

15
นอกจากนี้ทราบว่ามีวิธีการตรวจสอบว่าผู้ใช้ไม่ถูกเชื่อมต่อกับอินเทอร์เน็ต; ทั้งหมดที่คุณสามารถบอกได้คือถ้าพวกเขาได้รับการเชื่อมต่อในอดีตที่ผ่านมา สมมติว่าคุณมีวิธี: "bool c = IsConnected (); ถ้า (c) {DoSomething ();}" - ระหว่างการโทรไปยัง IsConnected และ DoSomething เราเตอร์เครือข่ายไร้สายอาจถูกถอดปลั๊ก IsConnected จริง ๆ ควรเรียกว่า WasRecentlyConnected
Eric Lippert

Windows NLM APIควรเป็นสิ่งที่ดีที่สุดสำหรับเรื่องนี้ stackoverflow.com/questions/5405895/…
Mahbubur Rahman

คำตอบ:


292

สิ่งนี้จะทำงานได้ดี

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
นี่อาจจะดีกว่าส่ง Ping ไปยัง Google เพราะฉันคิดว่าเราไม่รับประกันว่า Google จะยังคงตอบสนองต่อการส่ง Ping ในทางกลับกันฉันไม่สามารถนึกภาพโลกที่ www.google.com จะไม่ส่งคืน HTML บางส่วน :)
Daniel Vassallo

3
@Daniel: จริงในด้านหนึ่ง แต่ในทางกลับกันจริง ๆ แล้วการดาวน์โหลดเว็บไซต์เป็นค่าใช้จ่ายเล็กน้อย imo
Leo

9
ไม่ว่าจะด้วยเหตุผลใดก็ตามให้ดึง 4KB กลับมา - ใช้ไคลเอนต์ OpenRead (url) แทน หากไม่เกิดข้อยกเว้นแสดงว่าสามารถเชื่อมต่อได้
Josh M.

14
ที่จริงแล้วไม่มีประสิทธิภาพ การใช้สิ่งนั้นทำให้โปรแกรมของฉันเริ่มต้นใหม่ภายใน 1 นาทีหากไม่มีอินเทอร์เน็ต อาจเป็นเพราะพยายามแก้ไข DNS ส่ง Ping 8.8.8.8 (google dns) เปลี่ยนเป็น 3 วินาที
MadBoy

8
I cannot image a world where www.google.com does not return some HTMLตัวอย่างเช่น@DanielVassallo ในจีน ...
Jérôme MEVEL

84

ไม่มีทางที่คุณสามารถตรวจสอบได้อย่างน่าเชื่อถือว่ามีการเชื่อมต่ออินเทอร์เน็ตหรือไม่ (ฉันถือว่าคุณหมายถึงการเข้าถึงอินเทอร์เน็ต)

อย่างไรก็ตามคุณสามารถขอทรัพยากรที่แทบไม่เคยออฟไลน์เช่นส่ง Ping ไปที่ google.com หรืออะไรทำนองนั้น ฉันคิดว่ามันจะมีประสิทธิภาพ

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 "ไม่มีทางที่คุณจะสามารถตรวจสอบได้อย่างน่าเชื่อถือว่ามีการเชื่อมต่ออินเทอร์เน็ตหรือไม่"
woz

6
ทั้งหมดนี้คือการตรวจสอบว่า google จะขึ้นเมื่อคุณ ping หากการโต้ตอบแบบทันทีต่อไปหลังจาก ping อินเทอร์เน็ตที่ประสบความสำเร็จของคุณลดลง ไม่มีจุดในการตรวจสอบก่อนทำ
dbasnett

12
และสิ่งนี้ขัดแย้งกับคำแถลงหลักของคำตอบของฉันอย่างไร
Leo

10
การใช้ "google.com" จะใช้เวลามากกว่านี้เนื่องจากต้องได้รับการแก้ไข การส่ง Ping โดยตรงโดยใช้ IP จะเร็วขึ้นแทน ส่งไปยังที่อยู่ IP สาธารณะ DNS สาธารณะของ Google ( 8.8.8.8หรือ8.8.4.4) ใช้ได้ดีสำหรับฉัน
Mangesh

8
ผมอยากจะย้ำจุดที่Beware - many schools and offices block the ping protocol.ถ้าคุณกำลังใช้วิธีการนี้สำหรับโปรแกรมที่จะถูกใช้โดยลูกค้าผมจะให้คำแนะนำกับวิธีการนี้ในการตรวจสอบอินเทอร์เน็ต
user1

42

แทนที่จะทำการตรวจสอบเพียงดำเนินการ (คำขอเว็บ, เมล, ftp, ฯลฯ ) และเตรียมพร้อมสำหรับคำขอล้มเหลวซึ่งคุณต้องทำต่อไปแม้ว่าเช็คของคุณจะสำเร็จ

พิจารณาสิ่งต่อไปนี้:

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

หากเครือข่ายไม่ทำงานการกระทำของคุณจะล้มเหลวเช่นเดียวกับการปิงเป็นต้น

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

9
ขวา! แค่ทำ - แต่เตรียมพร้อมสำหรับผลลัพธ์ทั้งหมด
พันเอก Panic

3
ลองพิจารณาสิ่งต่อไปนี้: คุณต้องทำอะไรสักอย่างหากเครือข่ายหยุดทำงานเป็นเวลา x (เวลา tracelog รีเซตเราเตอร์)
Abir

2
ไม่ใช่ OP แต่เหตุผลที่ฉันต้องการทำเช่นนี้คือหลีกเลี่ยงการเสียเวลา 100 วินาทีหากการเชื่อมต่ออินเทอร์เน็ตไม่พร้อมใช้งาน คำขอ HTTP ถูกทำบนเธรดพื้นหลังดังนั้นเธรด UI จะไม่ถูกบล็อก แต่แอปของฉันไม่สามารถออกได้จนกว่าเธรดพื้นหลังจะส่งคืนจากคำขอ HTTP และยกเลิก แทนที่จะพยายามหาค่าการหมดเวลา "แฮปปี้มีเดีย" บางอย่างฉันต้องการหลีกเลี่ยงการร้องขอทั้งหมดหากฉันรู้ว่าการเชื่อมต่ออินเทอร์เน็ตไม่ทำงาน
Scott Smith

2
ประเด็นของฉันคือเราไม่สามารถบัญชีได้เมื่อบริการระยะไกลอาจพร้อมใช้งาน / ไม่พร้อมใช้งาน นอกจากนี้ไซต์ที่ไม่ตอบสนองต่อการปิงล่ะ
dbasnett

อีกกรณีการใช้งานคือตัวตรวจสอบออนไลน์ที่จะแจ้งเตือนฉันทันทีที่อินเทอร์เน็ตของฉันกลับมา
Ben Philipp

28

NetworkInterface.GetIsNetworkAvailableไม่น่าเชื่อถือมาก เพียงแค่มี VMware หรือการเชื่อมต่อ LAN อื่น ๆ และจะส่งคืนผลลัพธ์ที่ผิด เกี่ยวกับDns.GetHostEntryวิธีการที่ฉันเพิ่งกังวลว่า URL ทดสอบอาจถูกบล็อกในสภาพแวดล้อมที่แอปพลิเคชันของฉันจะปรับใช้หรือไม่

ดังนั้นอีกวิธีที่ฉันพบคือใช้InternetGetConnectedStateวิธีการ รหัสของฉันคือ

[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);         
}

ในระหว่างการทดสอบฉันพบว่า InternetGetConnectedState คืนค่าจริงเมื่อติดตั้งโปรแกรมเล่น VMWare (ตัดการเชื่อมต่ออินเทอร์เน็ต) จำเป็นต้องปิดการใช้งานในแผงควบคุม \ เครือข่ายและการเชื่อมต่ออินเทอร์เน็ต \ เครือข่าย (VMNet1 และ VMNet8)
HockeyJ

Ok Justin Oringer แม้ว่าฉันจะได้ตรวจสอบแล้ว แต่ต้องยืนยันอีกครั้ง
Kamran Shahid

2
วิธีที่ดีที่สุดสำหรับฉันฉันยังคงตรวจสอบการเชื่อมต่อบริการของฉันหลังจากนั้นเริ่มกิจวัตรประจำวัน ... ฉันแค่ต้องการหลีกเลี่ยงข้อยกเว้น
Wagner Bertolini Junior

4
รหัสนี้จะตรวจสอบว่าเสียบสายเคเบิลเครือข่ายไว้หรือไม่
HackerMan

14

ทดสอบการเชื่อมต่ออินเทอร์เน็ตโดยส่ง Ping ไปที่ Google:

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

7
คำอธิบายที่จะไปพร้อมกับคำตอบนี้จะเป็นประโยชน์กับผู้คนมากกว่าแค่ผู้เขียนคำถามดั้งเดิม
Boeckm

13
ระวัง - โรงเรียนและสำนักงานหลายแห่งบล็อคโปรโตคอลปิง โง่ฉันรู้
พันเอก Panic

ฉันหาคลาส ping ไม่พบ คุณจะกรุณาช่วยฉันหน่อยได้ไหม. ฉันกำลังทำงานกับ UWP และวิธีอื่น ๆ ในการตรวจสอบข้อมูลเครือข่ายไม่ทำงาน
iam.Carrot

12

ฉันไม่เห็นด้วยกับคนที่ระบุว่า: "อะไรคือจุดสำคัญในการตรวจสอบการเชื่อมต่อก่อนที่จะปฏิบัติงานทันทีหลังจากการตรวจสอบการเชื่อมต่ออาจสูญหาย" แน่นอนว่ามีระดับความไม่แน่นอนในงานเขียนโปรแกรมหลายอย่างที่เราในฐานะนักพัฒนา แต่การลดความไม่แน่นอนลงสู่ระดับการยอมรับนั้นเป็นส่วนหนึ่งของความท้าทาย

ฉันเพิ่งพบปัญหานี้ทำให้แอปพลิเคชันซึ่งรวมถึงคุณลักษณะการแมปที่เชื่อมโยงกับเซิร์ฟเวอร์ไทล์ออนไลน์ ฟังก์ชั่นนี้จะถูกปิดการใช้งานเมื่อมีการขาดการเชื่อมต่ออินเทอร์เน็ต

การตอบกลับบางส่วนในหน้านี้นั้นดีมาก แต่ก็ทำให้เกิดปัญหาด้านประสิทธิภาพเช่นแขวนในกรณีที่ไม่มีการเชื่อมต่อ

นี่คือวิธีแก้ปัญหาที่ฉันใช้ด้วยความช่วยเหลือของคำตอบเหล่านี้และเพื่อนร่วมงานของฉัน:

         // 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

ฉันได้เห็นตัวเลือกทั้งหมดที่ระบุไว้ข้างต้นและตัวเลือกเดียวที่ทำงานได้เพื่อตรวจสอบว่าอินเทอร์เน็ตใช้ได้หรือไม่นั้นเป็นตัวเลือก "ปิง" การนำเข้า [DllImport("Wininet.dll")]และ System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces() หรือรูปแบบอื่น ๆ ของ NetworkInterface คลาสใช้งานไม่ได้ในการตรวจสอบความพร้อมใช้งานของเครือข่ายวิธีการเหล่านี้จะตรวจสอบว่าเสียบสายเครือข่ายหรือไม่เท่านั้น

"ตัวเลือกปิง"

if(การเชื่อมต่อพร้อมใช้งาน) ส่งคืน true

if(ไม่มีการเชื่อมต่อและสายเคเบิลเครือข่ายเสียบอยู่) จะกลับมา false

if(ไม่ได้เสียบสายเครือข่าย) Throws an exception

NetworkInterface

if(มีอินเทอร์เน็ตให้ใช้) ส่งคืน True

if(อินเทอร์เน็ตไม่พร้อมใช้งานและเสียบสายเครือข่าย) True

if(สายเคเบิลเครือข่ายไม่ได้เสียบปลั๊ก) จะส่งคืน false

[DllImport ("Wininet.dll")]

if(มีอินเทอร์เน็ตให้ใช้) ส่งคืน True

if(อินเทอร์เน็ตไม่พร้อมใช้งานและเสียบสายเครือข่าย) True

if(สายเคเบิลเครือข่ายไม่ได้เสียบปลั๊ก) จะส่งคืน false

ดังนั้นในกรณีที่[DllImport("Wininet.dll")] และ NetworkInterface ไม่มีทางรู้ว่าการเชื่อมต่ออินเทอร์เน็ตสามารถใช้ได้


นี่ไม่เป็นความจริงฉันนำเข้า Wininet.dll สายเคเบิลเครือข่ายที่เสียบแล้วและได้ผลลัพธ์ที่ถูกต้องสำหรับสถานการณ์อินเทอร์เน็ตที่ไม่พร้อมใช้งาน
Waldemar Gałęzinowski

8

ไม่ได้ช่วยแก้ปัญหาของเครือข่ายที่หยุดทำงานระหว่างการตรวจสอบและเรียกใช้รหัสของคุณ แต่ค่อนข้างน่าเชื่อถือ

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;
}

ความคิดที่ดี แต่อย่างที่คุณพูดอาจไม่สมบูรณ์แบบ คุณสามารถแคชไบต์ที่ส่ง / รับเช่นกันสำหรับการตรวจสอบในอนาคต ยังไม่สมบูรณ์แบบแม้ว่า
ทอดด์

รหัสนี้ใช้งานไม่ได้โปรดแก้ไขให้ถูกต้อง จะตรวจสอบว่าเสียบสายเครือข่ายหรือไม่เท่านั้น
HackerMan

5

ส่ง Ping ไปที่ google.com แนะนำการแก้ไขปัญหา DNS กำลังส่ง Ping 8.8.8.8 ใช้ได้ แต่ Google อยู่ห่างจากฉันหลายครั้ง สิ่งที่ฉันต้องทำคือการ ping สิ่งที่ใกล้ที่สุดกับฉันที่อยู่ในอินเทอร์เน็ต

ฉันสามารถใช้คุณสมบัติ TTL ของ Ping เพื่อ ping hop # 1 จากนั้น hop # 2 เป็นต้นจนกว่าฉันจะได้รับคำตอบจากสิ่งที่อยู่บนเส้นทางที่ส่งไปได้ ถ้าโหนดนั้นอยู่ในเส้นทางที่อยู่ได้มันจะอยู่บนอินเทอร์เน็ต สำหรับพวกเราส่วนใหญ่ hop # 1 จะเป็นเกตเวย์ / เราเตอร์ในพื้นที่ของเราและ hop # 2 จะเป็นจุดแรกในด้านอื่น ๆ ของการเชื่อมต่อไฟเบอร์ของเราหรืออะไรก็ตาม

รหัสนี้ใช้งานได้สำหรับฉันและตอบสนองได้เร็วกว่าคำแนะนำอื่น ๆ ในชุดข้อความนี้เนื่องจากกำลังกระตุกสิ่งใดก็ตามที่อยู่ใกล้ฉันที่สุดบนอินเทอร์เน็ต

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

ต่อไปนี้คือวิธีการใช้งานใน Android

เพื่อเป็นการพิสูจน์แนวคิดฉันได้แปลรหัสนี้เป็น 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

อีกตัวเลือกหนึ่งคือ API ผู้จัดการรายชื่อเครือข่ายที่มีอยู่สำหรับ Vista และ Windows 7 MSDN บทความที่นี่ ในบทความนี้มีลิงค์สำหรับดาวน์โหลดตัวอย่างโค้ดซึ่งให้คุณทำสิ่งนี้:

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

อย่าลืมเพิ่มการอ้างอิงไปยังไลบรารีรายการประเภทเครือข่าย 1.0 จากแท็บ COM ... ซึ่งจะแสดงเป็น NETWORKLIST


7
eeeeww ใช้ COM Hell ใน. NET หรือไม่
jgauffin

@jgauffin คุณสามารถอธิบายได้ไหมว่าทำไมเราควรหลีกเลี่ยง COM ใน. NET เมื่อเทียบกับโซลูชันอื่น ๆ ที่ฉันพบโซลูชัน COM ดูเหมือนจะทำงานได้ค่อนข้างดี
inexcitus

2

พยายามหลีกเลี่ยงการทดสอบการเชื่อมต่อโดยการจับข้อยกเว้น เพราะเราคาดหวังจริงๆว่าบางครั้งเราอาจสูญเสียการเชื่อมต่อเครือข่าย

 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 มาจากไหน แก้ไข: ฉันพบมัน: System.Net.NetworkInformation
inspire_coding

1

หากคุณต้องการแจ้งให้ผู้ใช้ / ดำเนินการเมื่อใดก็ตามที่มีการเปลี่ยนแปลงเครือข่าย / การเชื่อมต่อเกิดขึ้น
ใช้ NLM API:


1

ฉันหาคำตอบของAnton และ moffeltje ให้ดีที่สุด แต่ฉันเพิ่มการตรวจสอบเพื่อแยกเครือข่ายเสมือนที่ติดตั้งโดย VMWare และอื่น ๆ

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 จากเอกสาร GetIsNetworkAvailable (): การเชื่อมต่อเครือข่ายได้รับการพิจารณาว่าพร้อมใช้งานหากอินเตอร์เฟสเครือข่ายใด ๆ ถูกทำเครื่องหมาย "up" และไม่ใช่อินเตอร์เฟสแบบย้อนกลับหรือช่องสัญญาณอุโมงค์ ฉันไม่รู้ว่าเสมือนจะอยู่ในชื่อหรือคำอธิบายของอินทราเซียสหรือไม่ เป็นมาตรฐานหรือไม่
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
คุณสามารถเพิ่มข้อมูลที่เกี่ยวข้องกับความเร็วของสิ่งนี้และวิธีนี้ดีกว่าโซลูชั่นอื่น ๆ ที่โพสต์หรือไม่ นี่จะช่วยให้คำตอบของคุณในการตอบคำถามอย่างเต็มที่
Ren

8
ปัญหาของตัวเลือกนี้คือbbจะยังคงเป็นจริงแม้ว่าเครือข่ายไม่ได้เชื่อมต่อกับอินเทอร์เน็ต
halfpastfour.am

2
ในขณะที่มันเป็นความจริงที่ว่านี้ไม่ได้ตอบคำถามโดยตรงฉันคิดว่ามันยังมีประโยชน์ในการใช้ GetIsNetworkAvailable เป็น pre-check ก่อนพยายาม ping Google เป็นต้น
Ben Hughes

3
รหัสนี้ไม่ได้บอกว่ามีการเชื่อมต่ออินเทอร์เน็ตหรือไม่ หากคุณเสียบสายเคเบิลเครือข่ายโดยไม่มีอินเทอร์เน็ตมันจะกลับมาจริง
HackerMan

1

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

ฉันจะไม่คิดว่ามันเป็นไปไม่ได้ แต่ไม่ใช่ตรงไปตรงมา

ฉันได้สร้างบางสิ่งเช่นนี้และใช่มันไม่สมบูรณ์แบบ แต่ขั้นตอนแรกนั้นสำคัญสำหรับการตรวจสอบว่ามีการเชื่อมต่อเครือข่ายหรือไม่ Windows Api ทำงานได้ไม่ดีนักดังนั้นทำไมไม่ทำงานให้ดีกว่านี้?

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;
}

มันค่อนข้างง่าย แต่ช่วยปรับปรุงคุณภาพของการตรวจสอบโดยเฉพาะอย่างยิ่งเมื่อคุณต้องการตรวจสอบการกำหนดค่าพร็อกซีต่างๆ

ดังนั้น:

  • ตรวจสอบว่ามีการเชื่อมต่อเครือข่ายหรือไม่ (ทำให้สิ่งนี้ดีมากบางทีอาจมีการส่งบันทึกกลับไปยังนักพัฒนาเมื่อมีข้อผิดพลาดที่เป็นเท็จเพื่อปรับปรุงฟังก์ชัน NetworkIsAvailable)
  • HTTP Ping
  • (วนผ่านการกำหนดค่าพร็อกซีด้วย HTTP Pings ในแต่ละรายการ)

1
@hackerman นี่เป็นขั้นตอนแรกที่ไม่ชัดเจน โคเดอร์สามารถทำงาน ping อย่างรวดเร็วไปยังเซิร์ฟเวอร์ของตัวเองถ้ามันคืนค่าจริงเป็นขั้นตอนที่สอง ที่สำคัญนี่เป็นทางเลือกหนึ่งของวิธีการที่ผิดพลาดของ windows api ที่เหลือก็เป็นรายละเอียด
ทอดด์

3
เพื่อปลอมแปลง หากไม่มีส่วนต่อประสานเครือข่ายเกิดขึ้นแสดงว่าไม่มีอินเทอร์เน็ตแน่นอน UI สามารถอัปเดตได้ทันทีโดยไม่ล่าช้าไม่มีการตรวจสอบโฮสต์อื่นเพิ่มเติม
ทอดด์

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;
    }
}

โปรดแสดงความคิดเห็นคำตอบของคุณ ไม่อนุญาตให้ใช้คำตอบที่มีรหัสเท่านั้น
ganchito55

มันเป็นคำอธิบายที่ค่อนข้างดีสำหรับการรักษาเพื่อการรักษา?
ม้วน

0

ใช้NetworkMonitorเพื่อตรวจสอบสถานะเครือข่ายและการเชื่อมต่ออินเทอร์เน็ต

ตัวอย่าง:

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");
        }
    }
}

เป็นความคิดที่ดี แต่ตรวจสอบความพร้อมของเครือข่ายไม่ใช่ความพร้อมให้บริการอินเทอร์เน็ต
John Demetriou

คลาสนี้ยังตรวจสอบความพร้อมของอินเทอร์เน็ต: SourceCode

มันคือสิ่งที่ฉันลอง แต่มันก็แค่ยิงถ้าไม่มีเครือข่าย
John Demetriou

0

บทนำ

ในบางสถานการณ์คุณต้องตรวจสอบว่ามีอินเทอร์เน็ตหรือไม่ใช้รหัส C # ในแอปพลิเคชัน windows อาจเป็นการดาวน์โหลดหรืออัพโหลดไฟล์โดยใช้อินเทอร์เน็ตในรูปแบบ windows หรือเพื่อรับข้อมูลบางอย่างจากฐานข้อมูลซึ่งอยู่ในสถานที่ห่างไกลในสถานการณ์เหล่านี้การตรวจสอบอินเทอร์เน็ตเป็นสิ่งจำเป็น

มีบางวิธีในการตรวจสอบความพร้อมใช้งานอินเทอร์เน็ตโดยใช้ C # จากโค้ดด้านหลัง ทุกวิธีดังกล่าวอธิบายไว้ที่นี่รวมถึงข้อ จำกัด

  1. InternetGetConnectedState (wininet)

API 'wininet' สามารถใช้เพื่อตรวจสอบว่าระบบโลคัลมีการเชื่อมต่ออินเทอร์เน็ตที่ใช้งานอยู่หรือไม่ เนมสเปซที่ใช้สำหรับสิ่งนี้คือ 'System.Runtime.InteropServices' และนำเข้า dll 'wininet.dll' โดยใช้ DllImport หลังจากสิ่งนี้สร้างตัวแปรบูลีนด้วยสแตติกภายนอกที่มีชื่อฟังก์ชั่น InternetGetConnectedState พร้อมคำอธิบายพารามิเตอร์สองรายการและ ReservValue ตามที่แสดงในตัวอย่าง

หมายเหตุ: ตัวดัดแปลงภายนอกใช้เพื่อประกาศวิธีการที่นำมาใช้ภายนอก การใช้งานภายนอกของตัวดัดแปลง extern อยู่กับแอ็ตทริบิวต์ DllImport เมื่อคุณใช้บริการ Interop เพื่อโทรเข้าสู่โค้ดที่ไม่มีการจัดการ ในกรณีนี้วิธีการจะต้องประกาศว่าเป็นแบบคงที่

ถัดไปสร้างวิธีที่มีชื่อ 'IsInternetAvailable' เป็นบูลีน ฟังก์ชั่นด้านบนจะใช้ในวิธีการนี้ซึ่งจะคืนค่าสถานะอินเทอร์เน็ตของระบบภายในเครื่อง

[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. GetIsNetworkAvailable

ตัวอย่างต่อไปนี้ใช้วิธี GetIsNetworkAvailable เพื่อตรวจสอบว่ามีการเชื่อมต่อเครือข่ายหรือไม่

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");
}

ข้อสังเกต (ตาม MSDN): การเชื่อมต่อเครือข่ายได้รับการพิจารณาว่าสามารถใช้งานได้หากอินเตอร์เฟสเครือข่ายใด ๆ ถูกทำเครื่องหมาย "up" และไม่ได้เป็นอินเตอร์เฟสย้อนกลับหรือช่องสัญญาณย้อนกลับ

มีหลายกรณีที่อุปกรณ์หรือคอมพิวเตอร์ไม่ได้เชื่อมต่อกับเครือข่ายที่มีประโยชน์ แต่ก็ยังถือว่าใช้ได้และ GetIsNetworkAvailable จะกลับมาจริง ตัวอย่างเช่นหากอุปกรณ์ที่รันแอปพลิเคชันเชื่อมต่อกับเครือข่ายไร้สายที่ต้องใช้พร็อกซี แต่ไม่ได้ตั้งค่าพร็อกซี GetIsNetworkAvailable จะกลับมาเป็นจริง อีกตัวอย่างหนึ่งที่ว่า GetIsNetworkAvailable จะกลับมาจริงเมื่อแอปพลิเคชันทำงานบนคอมพิวเตอร์ที่เชื่อมต่อกับฮับหรือเราเตอร์ที่ฮับหรือเราเตอร์สูญเสียการเชื่อมต่ออัปสตรีม

  1. Ping ชื่อโฮสต์บนเครือข่าย

คลาส Ping และ PingReply อนุญาตให้แอปพลิเคชันตรวจสอบว่าคอมพิวเตอร์ระยะไกลสามารถเข้าถึงได้ผ่านเครือข่ายหรือไม่โดยรับการตอบกลับจากโฮสต์ คลาสเหล่านี้มีอยู่ใน System.Net.NetworkInformation namespace ตัวอย่างต่อไปนี้แสดงวิธีการ ping โฮสต์

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;
}

ข้อสังเกต (ตาม MSDN): แอปพลิเคชันใช้คลาส Ping เพื่อตรวจสอบว่าสามารถเข้าถึงคอมพิวเตอร์ระยะไกลได้หรือไม่ โทโพโลยีเครือข่ายสามารถกำหนดได้ว่า Ping สามารถติดต่อโฮสต์ระยะไกลได้สำเร็จ การมีอยู่และการกำหนดค่าพร็อกซีอุปกรณ์การแปลที่อยู่เครือข่าย (NAT) หรือไฟร์วอลล์สามารถป้องกัน Ping ไม่ให้สำเร็จ Ping ที่ประสบความสำเร็จบ่งชี้ว่าสามารถเข้าถึงรีโมตโฮสต์ได้บนเครือข่ายเท่านั้น ไม่สามารถรับประกันการมีอยู่ของบริการระดับสูงกว่า (เช่นเว็บเซิร์ฟเวอร์) บนโฮสต์ระยะไกล

ความคิดเห็น / ข้อเสนอแนะได้รับเชิญ มีความสุขการเข้ารหัส ......


-1

สำหรับแอปพลิเคชันของฉันเรายังทดสอบโดยดาวน์โหลดไฟล์เล็ก ๆ

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;
}

ด้วย ISP บางรายอาจใช้เซิร์ฟเวอร์กลางเพื่อแคชไฟล์ เพิ่มพารามิเตอร์ที่ไม่ได้ใช้แบบสุ่มเช่น https://www.microsoft.com/favicon.ico?req=random_number สามารถป้องกันการแคช


-1

ฉันมีปัญหาเกี่ยวกับวิธีการเหล่านั้นบน 3g เราเตอร์ / โมเด็มของฉันเพราะถ้าอินเทอร์เน็ตถูกตัดการเชื่อมต่อเราเตอร์จะเปลี่ยนเส้นทางหน้าไปยังหน้าการตอบสนองดังนั้นคุณยังคงได้รับไอน้ำและรหัสของคุณคิดว่ามีอินเทอร์เน็ต แอปเปิ้ล (หรืออื่น ๆ ) มีหน้าฮอตสปอต - อุทิศซึ่งจะส่งกลับคำตอบที่แน่นอน ตัวอย่างต่อไปนี้ส่งคืนการตอบสนอง "สำเร็จ" ดังนั้นคุณจะมั่นใจได้ว่าคุณสามารถเชื่อมต่ออินเทอร์เน็ตและรับการตอบสนองที่แท้จริง!

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

ฉันมีสามการทดสอบสำหรับการเชื่อมต่ออินเทอร์เน็ต

  • เอกสารอ้างอิงSystem.NetและSystem.Net.Sockets
  • เพิ่มฟังก์ชั่นการทดสอบต่อไปนี้:

ทดสอบ 1

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

ทดสอบ 2

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

ทดสอบ 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;
    }
}

ทำการทดสอบ

ถ้าคุณทำDictionaryของStringและBooleanเรียกว่าคุณสามารถเพิ่มผลของแต่ละการทดสอบเพื่อCheckListCheckList

ทีนี้ให้แต่ละอันKeyValuePairใช้การfor...eachวนซ้ำ

ถ้าCheckListมีValueของtrueแล้วคุณรู้ว่ามีการเชื่อมต่ออินเทอร์เน็ต


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

ที่ได้ผล


46
หากคุณมี IP ของ Google ในแคช DNS ของคุณจะไม่ส่งคำขอ DNS ดังนั้นจึงสามารถส่งคืนได้แม้ว่าคุณจะไม่ได้เชื่อมต่อก็ตาม
Thomas Levesque
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.