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

Posted

技术标签:

【中文标题】验证有可用网络连接的最简单方法是啥?【英文标题】:What's the easiest way to verify there's an available network connection?验证有可用网络连接的最简单方法是什么? 【发布时间】:2010-10-05 04:54:28 【问题描述】:

我是 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 interface”。

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

G

【问题讨论】:

【参考方案1】:

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

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

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

【讨论】:

如果我错了,请纠正我,但这不会也枚举蓝牙吗?这似乎是一个不受欢迎的结果。【参考方案2】:

还有一些要记住的事情:

可用的网络连接!= 可用的互联网连接。 Internet 访问!= 访问特定网站(想想代理过滤器,或者该网站可能已关闭)

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

这些资源是不稳定的;无论如何,当它们出现故障时,您必须处理异常。因此,通常最好只是去获取一个资源,就好像您确定它存在一样,并投入开发时间以确保您的异常处理程序能够很好地处理故障。

【讨论】:

感谢您的提醒。那么 try/catch 处理是否是选择是否在离线模式下调整程序的最佳方式?我会在适当的时候研究一种离线存储这些数据的方法,但我想自己解决一些问题:-) 我的 0.02 美元是第一次失败时,提示用户是否要重试或进入离线模式。如果他们进入离线模式,请保持离线模式,直到他们单击按钮尝试再次在线。【参考方案3】:

这是课程

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
    
 

【讨论】:

哇!非常好,非常感谢。我会在接下来的几天内对此进行调查。【参考方案4】:

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

【讨论】:

好的,我想看看对我来说非常有用的代码 我会把它清理干净并在这里发布。希望它会根据我的工作量在一天内发布。 如果那台计算机因某种原因被移除,这不会倒下吗?我希望您有充分的文件证明系统需要启动才能继续工作。 是的,但对于我们的应用程序,我们将我们的软件与其他关键任务应用程序一起托管在客户设施的专用服务器上。我们正在 ping 一个不应该被删除或关闭的服务器。

以上是关于验证有可用网络连接的最简单方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在 spring boot angular 8 webapp 中验证和管理用户的最简单方法是啥?

在 Mac OS X 上安装本地 LAMP 以进行 Web 开发的最简单方法是啥?

在云服务器中运行 python 脚本的最简单方法是啥?

使用 SSH 和 NFS 在集群上进行并行化的最简单方法是啥?

在用户注销后防止浏览器的后退按钮显示安全数据的最简单方法是啥?

从IP地址获取用户纬度和经度的最简单方法是啥[关闭]