using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Net.NetworkInformation; using System.Threading; using Ursa.Controls; using 常用工具集.Base; namespace 常用工具集.ViewModel._02网络相关 { public class 网络状态检测ViewModel : ViewModelBase { #region 数据 public ObservableCollection PingStatus { get; set; } private int ip1 { get; set; } = 172; public int IP1 { get { return ip1; } set { ip1 = value; SetTip(); NotifyPropertyChanged(); } } private int ip2 { get; set; } = 16; public int IP2 { get { return ip2; } set { ip2 = value; SetTip(); NotifyPropertyChanged(); } } private int ip3 { get; set; } = 0; public int IP3 { get { return ip3; } set { ip3 = value; SetTip(); NotifyPropertyChanged(); } } #endregion public DelegateCommand Button1Cmd { get; set; } public DelegateCommand Button2Cmd { get; set; } public 网络状态检测ViewModel() { lock (_lock) { PingStatus = new ObservableCollection(); for (int i = 1; i <= 255; i++) { PingStatus.Add(new MyPingStatus { Index = i, IpAddress = $"{IP1}.{IP2}.{IP3}.{i}", Color = "#FFFF80", Tip = $"{IP1}.{IP2}.{IP3}.{i}", Status = false }); } } threadList = new List(); SetTip(); Button1Cmd = new DelegateCommand(Button1CmdFunc); Button2Cmd = new DelegateCommand(Button2CmdFunc); } private List threadList; private void Button1CmdFunc(object obj) { lock (pingLock) { if (IPPool.Count > 0) { MessageBox.ShowAsync("上一次操作还没结束,请等待完成后继续"); return; } } lock (_lock) { SetColor("#FFFF80");//开始之前清除一下 } foreach (MyThread myThread in threadList) { myThread.Stop(); myThread.OnSendResult -= Thread_OnSendResult; } threadList.Clear(); lock (_lock) { for (int i = 1; i <= 255; i++) { IPPool.Add(i); } } string ip = $"{IP1}.{IP2}.{IP3}."; for (int i = 0; i < 10; i++) { MyThread thread = new MyThread(ip); thread.OnSendResult += Thread_OnSendResult; thread.Start(); threadList.Add(thread); } } private void Thread_OnSendResult(int endIndex, bool state) { if (state) { SetColor(endIndex, "#00FF00"); } else { SetColor(endIndex, "#FF0000"); } } private void Button2CmdFunc(object obj) { lock (pingLock) { if (IPPool.Count > 0) { MessageBox.ShowAsync("上一次操作还没结束,请等待完成后继续"); return; } } lock (_lock) { SetColor("#FFFF80"); } } /// /// 设置提示 /// private void SetTip() { foreach (MyPingStatus status in PingStatus) { status.Tip = $"{IP1}.{IP2}.{IP3}.{status.Index}"; } } /// /// 设置提示 /// private void SetColor(string color) { foreach (MyPingStatus status in PingStatus) { status.Color = color; } } internal static List IPPool = new List(); internal static object pingLock = new object(); internal object _lock = new object(); private void SetColor(int index, string color) { lock (_lock) { foreach (MyPingStatus status in PingStatus) { if (status.Index == index) { status.Color = color; break; } } } } } public class MyPingStatus : ViewModelBase { public int Index { get; set; } public string Color { get; set; } public string Tip { get; set; } public string IpAddress { get; set; } public bool Status { get; set; } } internal class MyThread { public delegate void SendResult(int endIndex, bool state); public event SendResult OnSendResult; private Thread thread; private string ipAddress; private bool stop; public MyThread(string ip) { this.ipAddress = ip; } public MyThread Start() { thread = new Thread(() => { while (true) { try { if (stop) break; //从IP池取出一个 int ipIndex = 0; lock (网络状态检测ViewModel.pingLock) { if (网络状态检测ViewModel.IPPool.Count > 0) { ipIndex = 网络状态检测ViewModel.IPPool[0]; 网络状态检测ViewModel.IPPool.RemoveAt(0); } } if (ipIndex == 0) break; bool flag = Ping($"{ipAddress}{ipIndex}"); OnSendResult?.Invoke(ipIndex, flag); } catch (Exception ex) { if (ex is ThreadInterruptedException) break; } } }); thread.Start(); return this; } public void Stop() { stop = true; thread.Interrupt(); } private bool Ping(string ip) { byte[] bytes = new byte[32]; for (int i = 0; i < bytes.Length; i++) { bytes[i] = (byte)(i + 1); } Ping ping = new Ping(); if (ping.Send(ip, 300, bytes, new PingOptions { Ttl = 255 }).Status == IPStatus.Success) { return true; } return false; } } }