网络接口状态监控程序

在开发需要网络连接的程序时,能够响应网络变化是非常有用的。本文将介绍如何使用.NET框架中的System.Net.NetworkInformation命名空间来监控网络接口的状态变化,并生成相应的事件。

.NET框架提供了一些有用的信息,这些信息与系统连接的网络接口有关,这些信息可以在System.Net.NetworkInformation命名空间中找到。特别是NetworkInterface类,它包含了一个静态方法GetAllNetworkInterfaces(),该方法返回一个NetworkInterface对象的数组,这些对象包含了有关机器上可用网络适配器的信息。

需要注意的是,重复调用GetAllNetworkInterfaces()方法总是返回相同的类的引用。因此,如果保留了一个网络接口的引用,然后调用GetAllNetworkInterfaces()并找到相同的适配器,然后比较两个操作状态属性;即使网络适配器在两次调用之间已连接或断开,操作状态属性也将是相同的,因为比较的是同一个对象。

为了能够测试两次调用GetAllNetworkInterfaces()方法之间的差异,需要另一个对象来填充第一次调用的属性值。然后可以将这个对象与当前值进行比较,从而检测到差异。

使用代码

附带的项目定义了两个重要的类:NetworkStatus和NetworkStatusMonitor。

这个类作为本地机器网络接口状态的记录,它在构造时保留了自己的NetworkInterface类属性的副本。它定义了一个内部类,实际上是网络接口状态的记录,并保留了这些类的集合。

public class NiStatusRecord { public NiStatusRecord(NetworkInterface ni) { Interface = ni; OperationalStatus = ni.OperationalStatus; Type = ni.NetworkInterfaceType; Speed = ni.Speed; } public NetworkInterface Interface { get; set; } public OperationalStatus OperationalStatus { get; set; } public NetworkInterfaceType Type { get; set; } public long Speed { get; set; } }

NetworkStatus类还实现了一些方法,用于将自己与另一个NetworkStatus类的实例进行比较。这些方法返回IEnumerable,网络状态监控类使用这些IEnumerable来确定哪些接口发生了变化:

public IEnumerable Connected(NetworkStatus lastStatus) { foreach (var pair in _status) { if (lastStatus._status.ContainsKey(pair.Key)) { if (lastStatus._status[pair.Key].OperationalStatus != OperationalStatus.Up && pair.Value.OperationalStatus == OperationalStatus.Up) { yield return pair.Value.Interface; } else { if (pair.Value.OperationalStatus == OperationalStatus.Up) { yield return pair.Value.Interface; } } } } }

NetworkStatusMonitor类运行一个循环方法(在自己的线程中,因此不会阻塞应用程序的其余部分),该方法存储一个新的NetworkStatus类实例,等待预定义的毫秒数,然后生成一个新的NetworkStatus类实例,并运行比较方法以识别任何已连接、断开连接等的适配器。

private void MonitorTask() { while (_run) { try { if (_last == null) { _last = new NetworkStatus(); Thread.Sleep(_waitInterval); continue; } else { NetworkStatus current = new NetworkStatus(); if (NetworkInterfaceConnected != null && _monitorNewConnections) { foreach (var ni in current.Connected(_last)) { NetworkInterfaceConnected(this, new StatusMonitorEventArgs() { EventType = StatusMonitorEventType.Connected, Interface = ni, LastOperationalStatus = lastStatus }); } } if (NetworkInterfaceDisconnected != null && _monitorDisconnections) { foreach (var ni in current.Disconnected(_last)) { NetworkInterfaceDisconnected(this, new StatusMonitorEventArgs() { EventType = StatusMonitorEventType.Disconnected, Interface = ni, LastOperationalStatus = OperationalStatus.Up }); } } if (NetworkInterfaceChanged != null && _monitorAnyStatusChange) { foreach (var ni in current.Changed(_last)) { NetworkInterfaceChanged(this, new StatusMonitorEventArgs() { EventType = StatusMonitorEventType.Changed, Interface = ni, LastOperationalStatus = lastStatus }); } } _last = current; if (_run) Thread.Sleep(_waitInterval); } lock (_pulse) Monitor.PulseAll(_pulse); } catch (Exception exception) { Console.WriteLine(exception.ToString()); Interlocked.Increment(ref _exceptionCount); } } }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485