验证可用网络连接的最简单方法是什么?

时间:2009-02-03 16:33:43

标签: c# .net .net-2.0 networking

我对c#/ .net开发有点新手,但我已经为我公司的一小部分资产整理了一个股票跟踪应用程序。我还在SQL 2000中设置了它连接的数据库。

当网络连接可用时,它目前工作得非常出色,但是当我远离连接时,我想扩展它以供使用。

首先,我需要知道是否有可用的连接。所以我把它放在一起:

    private int availableNetAdapters()
    {
        int nicCount = 0;
        foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
        {
            if (nic.OperationalStatus == OperationalStatus.Up)
            {
                nicCount++;
            }
        }

        return nicCount;
    }

似乎工作,但我必须测试“> 1”,因为无论其他适配器状态如何,始终都会检测到“MS TCP Loopback接口”。

是否有更好/更简单的方法来检查连接?

4 个答案:

答案 0 :(得分:9)

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

您还可以使用该类中的事件NetworkAvailabilityChangedNetworkAddressChanged来监控IP地址和网络可用性更改。

编辑:请注意,此方法会检查计算机上可能存在的所有可用网络接口(无线,局域网等)。如果其中任何一个已连接,它将返回true。

答案 1 :(得分:8)

还有一些事情需要记住:

  • Avaialable网络连接!=可用的互联网连接。
  • 互联网访问!=访问特定网站(想想代理过滤器,或网站可能只是关闭)

因此,通常最好直接测试对所需特定资源的访问。

这些资源不稳定;无论如何,你必须处理异常。因此,通常最好只获取一个资源,就像你确定它确实存在一样,并将开发时间用于确保你的异常处理程序在失败方面做得很好。

答案 2 :(得分:4)

这是班级

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;

namespace Ping
{    
    public readonly int iSent = 0;
    public readonly int iReceived = 0;
    public readonly int iLost = 0; 

    public PingReceivedArgs (int iSent, int iReceived, int iLost)
    {
        this.iSent = iSent;
        this.iReceived = iReceived;
        this.iLost = iLost;
    }

    public class PingFailedArgs : EventArgs
    {
        public readonly int iSent = 0;
        public readonly int iReceived = 0;
        public readonly int iLost = 0;

        public PingFailedArgs (int iSent, int iReceived, int iLost)
        {
            this.iSent = iSent;
            this.iReceived = iReceived;
            this.iLost = iLost;
        }
    }

/// <summary>
/// The Main Ping Class
/// </summary>
public class Ping
{
        //Create delegate for events
            public delegate void PingReceivedHandler(object DataObj, PingReceivedArgs PingReceived);
        public delegate void PingFailedHandler(object DataObj, PingFailedArgs PingFailed);

    //The events we publish
    public event PingReceivedHandler OnPingReceived;
    public event PingFailedHandler OnPingFailed;

    private void FirePingReceivedEvent( int iSent, int iReceived, int iLost)
    {
        PingReceivedArgs NewStatus = new PingReceivedArgs(iSent, iReceived, iLost);
        if (OnPingReceived != null)
        {
            OnPingReceived(this,NewStatus);
        }
    }

    private void FirePingFailedEvent(int iSent, int iReceived, int iLost)
    {
        PingFailedArgs NewStatus = new PingFailedArgs(iSent, iReceived, iLost);
        if (OnPingFailed != null)
        {
            OnPingFailed(this,NewStatus);
        }
    }


    private string _Host = "";
    private bool _HostFound = false;
    private int _PingSent = 0;
    private int _PingReceived = 0;
    private int _PingLost = 0;
    private int _PauseBetweenPings = 2000;
    private Thread _PingThread;

    public string  Host
    {
        get { return _Host; }
        set { _Host = value; }
    }
    public bool  HostFound
    {
        get { return _HostFound; }
    }
    public int PingSent
    {
        get { return _PingSent; }
    }
    public int PingReceived
    {
        get { return _PingReceived; }
    }
    public int PingLost
    {
        get { return _PingLost; }
    }

    public int  PauseBetweenPings
    {
        get { return _PauseBetweenPings; }
        set { _PauseBetweenPings = value; }
    }

    public Ping()
    {
        //
        // TODO: Add constructor logic here
        //
    }

    public void StartPinging()
    {
        try
        {
            if (_Host.Length == 0)
            {
                //LogStatus.WriteLog("Host name is blank,    stopping.","Error","StartPinging");
                return;
            }


               if (_PingThread == null || (_PingThread.ThreadState &    (System.Threading.ThreadState.Unstarted | System.Threading.ThreadState.Background)) == 0)
            {

                _PingThread = new Thread(new ThreadStart(LoopAndPing));
                _PingThread.IsBackground = true;
                _PingThread.Start();
            }
        }
        catch( Exception ex)    
        {
            //LogStatus.WriteErrorLog(ex,"Error","StartPinging");
        }
    }

    public void StopPinging()
    {
        try
        {
               if (_PingThread != null && (_PingThread.ThreadState &    (System.Threading.ThreadState.Stopped | System.Threading.ThreadState.Aborted |    System.Threading.ThreadState.Unstarted | System.Threading.ThreadState.AbortRequested)) ==    0)
            {
                _PingThread.Abort();
                _PingThread.Join();
            }
        }
        catch (Exception ex)
        {
            //LogStatus.WriteErrorLog(ex, "Error", "StopPinging");
        }
    }

    /// <summary>
    /// LoopAndPing: Runs from a thread.  Basically loops and gathers stats.
    /// </summary>
    private void LoopAndPing()
    {
        bool bHostFound = false;

        try
        {
            while(true)
            {
                _PingSent++;
                bHostFound = PingHost(_Host);
                if (bHostFound) 
                { 
                    _PingReceived++; 
                    _HostFound = true;
                       FirePingReceivedEvent(_PingSent,_PingReceived,_PingLost);
                }
                else  
                { 
                    _PingLost++; 
                    _HostFound = false;
                       FirePingFailedEvent(_PingSent,_PingReceived,_PingLost);
                }
                Thread.Sleep(_PauseBetweenPings);
            }
        }
        catch(ThreadAbortException)
        {
            //No need to do anything!
        }
        catch(Exception e)  
        {
            //LogStatus.WriteErrorLog(e,"Error","LoopAndPing");
        }
    }

    /// <summary>
    /// PingHost - Send one ping to the host
    /// </summary>
    /// <param name="host">Can be an IP or Host name.</param>
    /// <returns></returns>
    public bool PingHost(string szHost)
    {
        bool bPingWorked = false;

        try
        {
            string szCommand = "ping " + szHost + " -n 1";
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.Arguments = "/Q /A /C" + szCommand;
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            p.Start();
            string szCommandOutput = p.StandardOutput.ReadToEnd();
            p.WaitForExit();

            if (szCommandOutput.ToUpper().IndexOf("REPLY FROM") > -1)
            {
                bPingWorked = true;
            }
        }
        catch(ThreadAbortException)
        {
            //No need to do anything!
        }
        catch(Exception e)  
        {
            //LogStatus.WriteErrorLog(e,"Error","PingHost");
        }
        return bPingWorked;
    }
}
}

从客户端拨打

PingHost = new Ping();
PingHost.OnPingFailed += new Ping.PingFailedHandler(PingHost_OnPingFailed);
PingHost.OnPingReceived +=new Ping.PingReceivedHandler(PingHost_OnPingReceived);
PingHost.Host = *IP you wish to ping*;
PingHost.StartPinging();

然后,您将编写方法来捕获上面定义的PingHost事件

private void PingHost_OnPingReceived(object DataObj, PingReceivedArgs PingReceived)
{
    try
    {
        // code to do something when a successful ping occurrs
    }
    catch (Exception ex) 
    {
       // code to do something when an exception occurrs
    }
 }

private void PingHost_OnPingFailed(object DataObj, PingFailedArgs PingFailed)
{
    try
    {
            // code to do something when a ping failure occurrs
    }
    catch (Exception ex) 
    {
            // code to do something when an exception occurrs
    }
 }

答案 3 :(得分:0)

我们的应用主要在通过无线空中卡连接的警车上运行。我们需要一种方法来确定它们是否已连接。我们编写了一个非常小的Ping.cs类,它定期ping预定的IP或计算机名称。我们解释结果消息并更改系统托盘连接图标的显示。如果你愿意,我可以发给你C#代码。