C# WPF网络实时监测客户端
? ? ? ?前段時間一個客戶項目,現場部署的是無線網絡,使用我們系統的時候,發現總在某些時間段出現請求特別慢,并且客戶有三個工廠,一工廠、二工廠使用的沒問題,唯獨三工廠一直出現問題,經過幾次與客戶方IT交流,始終不承認是網絡有問題,估計是因為害怕擔責任,因此不得不寫一個程序,來實現實時網絡監測,以洗清我們的責任(這就是甲方和乙方,甲方是大爺,乙方不如甲方的狗)。
一、需求分析
? ? ? ? 我們的目標是實時監測網絡情況,我們沒有小工具前是如何做的呢?正常情況下,依靠windows系統的時候我們都是用打開命令窗口,用ping ip 的方式,看看網絡有沒有很大的延遲。好了,我們也不要做的太復雜,第一點就是實現這個ping。然后,我們想到,如果只是ping一次,那么我們還要這個工具干嘛?為啥不每次手動輸入呢?所以,第二點我們需要實現自動長時間ping,有點像 ping -t 的命令。我們只是查看這個結果還不行,還需要有個記錄,就像數據庫一樣的東西,記錄下來,這樣也好分析時間等等因素,這就是第三點,我們要實現日志記錄功能。再想想,還有什么需要我們做的嗎?對,如果能在界面上隨意添加一個ip,我們就可以實現ping,多好,對,這就是我們要實現的第四點功能,ip可以隨時添加,隨時移除。大概就是這么多了,以后有其他的功能在慢慢迭代吧!
?
二、概要設計
? ? ? ?首先,按照一個產品的生命周期來算,我應該出一個設計圖了,不管是用什么工具畫的,至少需要一個什么樣的圖,以指導開發,當然,這里的開發就我一個人,誰讓我沒有一個開發團隊呢(不用急,樓主以后肯定會有的)?好,下面我就用最簡單的windows 畫圖工具畫一個,簡單省事。
? ? ? ? ? ? ??
? ? ? ? ? 上面就是設計圖,是不是超簡單,但是清晰明了,我要的東西上面都有。
三、詳細設計
? ? ? ? ?下面就開始枯燥乏味的編碼了,嗯,就是編碼,而且是枯燥乏味的。
1、畫界面
? ? ? ? ?用的是WPF,所以界面的畫法其實跟前端寫頁面差不多,這里就直接上代碼了。
<Window x:Class="NetWork_Watch.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:NetWork_Watch"mc:Ignorable="d"Icon="Resource/ico.ico"ContentRendered="window_contentRendered"Closing="Window_Closing"Title="Network Watch" Height="700" Width="800" ResizeMode="CanMinimize"><Grid Name="MainGrid"><Grid.RowDefinitions><RowDefinition Height="300"/><RowDefinition Height="400"/></Grid.RowDefinitions><Grid Name="TopGrid" Grid.Row="0"><Grid.RowDefinitions><RowDefinition Height="300"></RowDefinition></Grid.RowDefinitions><Rectangle Fill="#EEEEEE" HorizontalAlignment="Right" Margin="0,0,400,10" Width="390"/><Rectangle Fill="#EEEEEE" Height="290" Margin="400,0,0,0" VerticalAlignment="Top" Width="390"/><Label x:Name="label" Content="設置" HorizontalAlignment="Left" FontSize="20" FontWeight="Bold" Margin="10,10,0,0" VerticalAlignment="Top"/><Label x:Name="ip_lab" Content="IP/網址:" FontSize="14" HorizontalAlignment="Left" Margin="40,80,0,0" VerticalAlignment="Top"/><TextBox x:Name="ip_tb" HorizontalAlignment="Left" FontSize="14" Height="30" Margin="120,80,0,0" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" Width="240"/><Button x:Name="remove_btn" Content="移 除" HorizontalAlignment="Left" Margin="69,180,0,0" VerticalAlignment="Top" Width="75" Height="30" FontSize="16" Click="button_remove_Click"/><Button x:Name="add_btn" Content="添 加" HorizontalAlignment="Left" Margin="270,180,0,0" VerticalAlignment="Top" Width="75" Height="30" FontSize="16" Click="button_add_Click"/><Label x:Name="label1" Content="IP/網址" HorizontalAlignment="Left" FontSize="20" FontWeight="Bold" Margin="420,10,0,0" VerticalAlignment="Top"/><DataGrid x:Name="log_dg" IsReadOnly="True" ItemsSource="{Binding}" HorizontalAlignment="Left" Margin="420,50,0,0" VerticalAlignment="Top" Height="230" Width="350" SelectionChanged="log_dg_SelectionChanged"><DataGrid.Columns><DataGridTextColumn Header="IP/網址" Width="150" Binding="{Binding ip}"/><DataGridTextColumn Header="創建時間" Width="*" Binding="{Binding createTime}"/></DataGrid.Columns></DataGrid></Grid><Grid Name="BottomGrid" Grid.Row="1" Margin="0,0,0,30"><Grid.RowDefinitions><RowDefinition Height="400"></RowDefinition></Grid.RowDefinitions><Rectangle Fill="#EEEEEE" HorizontalAlignment="Left" Margin="0,10,0,0" Width="800" Height="400" VerticalAlignment="Top"/><Label x:Name="label2" Content="日志統計" HorizontalAlignment="Left" Margin="10,20,0,0" FontSize="20" FontWeight="Bold" VerticalAlignment="Top"/><TextBox x:Name="log_tb" HorizontalAlignment="Left" Height="290" Margin="10,60,0,0" VerticalAlignment="Top" Width="760"/></Grid></Grid> </Window>對應的 vs 2015會顯示出界面效果,如下:
? ? ??
界面算是布局完成了,接下來,需要實現邏輯了。
2、實現添加、移除IP、網址功能
? ? ? ?要實現移除添加ip功能,其實就是對一個list 進行插入和刪除就行了。因為在這里做的比較簡單,所以沒有用存儲數據庫或者文件的方式進行序列化ip,而是每次打開這個小工具的時候進行添加要監聽的ip。
? ? ? 定義一個實體類,用來定義一個ip的添加時間以及ip地址,如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace NetWork_Watch {public class IpInfo{public string ip { set; get; }public string createTime { set; get; }public IpInfo(string ip){this.ip = ip;this.createTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");}} }對,很簡單,就是一個ip,一個創建時間,構造方法就是傳入一個ip,然后自動記錄時間。用一個全局的list來存儲當前所有插入的ip地址信息,寫在界面布局對應的cs文件中。
ObservableCollection<IpInfo> list = new ObservableCollection<IpInfo>();添加、移除按鈕事件如下:
private void button_add_Click(object sender, RoutedEventArgs e){bool flag = false;for(int i = 0; i< list.Count; i++){if(list[i].ip == ip_tb.Text){flag = true;break;}}if (!flag){IpInfo ipInfo = new IpInfo(ip_tb.Text);list.Add(ipInfo);log_tb.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+"-增加監聽客戶端:" + ipInfo.ip);log_tb.AppendText(Environment.NewLine);}else{MessageBox.Show("已存在需要添加的ip,無法重復添加。", "提示", MessageBoxButton.OK,MessageBoxImage.Error);}}private void button_remove_Click(object sender, RoutedEventArgs e){for (int i = 0; i < list.Count; i++){if (list[i].ip == ip_tb.Text){ip_tb.Text = null;log_dg.SelectedItem = null;list.RemoveAt(i);i--;}}}這樣就可以實現動態的添加、刪除ip了。
嗯,第一步效果實現了。
3、實現日志記錄功能
? ? ? ? 看到上面日志統計里面的信息了嗎?這個只會在程序開著的時候進行顯示,我現在要記錄到文件中怎么辦?聯想起Java 里面用的日志組件,log4j,嗯,肯定有c# 版的,打開NuGet,搜索,結果如下:
果然,有此神物,點擊安裝,然后創建配置文件,至于配置文件怎么配置在這就不詳細解說了。我的配置如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration><configSections><section name="log4net" type="System.Configuration.IgnoreSectionHandler"/></configSections><log4net><appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"><!--日志存儲位置--><file value="logs\log.log"/><appendToFile value="true"/><rollingStyle value="Composite"/><datePattern value="yyyyMMdd"/><maxSizeRollBackups value="10"/><maximumFileSize value="1MB"/><layout type="log4net.Layout.PatternLayout"><!--日志輸出格式--><conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/></layout></appender><root><level value="All"/><appender-ref ref="RollingLogFileAppender"/></root></log4net><startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup> </configuration>配置完日志就沒事了嗎?不,還有一步,必須配置不可,在AssemblyInfo.cs添加如下一行,相當于注冊組件吧!
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", ConfigFileExtension = "config", Watch = true)]配置好了,該使用了。
在類的最上面,實例化組件,
private static log4net.ILog logger = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);然后你就可以在你想要使用的地方瀟灑的使用了,例如:
logger.Info("增加監聽客戶端:" + ipInfo.ip);在我們項目文件夾下面,將會產生一個log的文件夾,這個是在config中配置的路徑,同時log文件夾中會有一個log文件,打開查看如下:
2019-03-26 10:41:19,763 [1] INFO NetWork_Watch.MainWindow - 增加監聽客戶端:192.168.113.15好了,日志功能實現了。
4、實現監聽
? ? ? ? 前面做了這么多,都是為了這一步做鋪墊,要想時刻進行監聽,就需要用一個循環,在不停的跑,然后實現實時監聽。其實我們只需要對存儲ip的list進行不斷的ping,即可完成需求。c# 的Ping 類可以解決我們發送請求的問題,while(true)可以實現我們不斷循環的需要。因此,我們就用這個來實現吧!
Thread _ping = null;ObservableCollection<IpInfo> list = new ObservableCollection<IpInfo>();public MainWindow(){InitializeComponent();_ping = new Thread(PingRemote);_ping.Start();}void PingRemote(){while (true) { for(int i = 0; i< list.Count; i++){string host = list[i].ip;PingReply reply = p1.Send(host,10); //發送主機名或Ip地址if (reply.Status == IPStatus.Success){logger.Info("遠程地址:" + host + "請求連接成功,往返時間:" + reply.RoundtripTime + ",TTL:" + reply.Options.Ttl);sendTBlog("遠程地址:" + host + "請求連接成功,往返時間:" + reply.RoundtripTime + ",TTL:" + reply.Options.Ttl); }else if (reply.Status == IPStatus.TimedOut){logger.Error("遠程地址:" + host + "請求連接超時!");sendTBlog("遠程地址:" + host + "請求連接超時!"); }else{logger.Error("遠程地址:" + host + "請求連接失敗!");sendTBlog("遠程地址:" + host + "請求連接失敗!");// 為了防止一直處于ping中,這里每次暫停10秒。 }Thread.Sleep(10*1000);}}}private void sendTBlog(string message){// 注意,此處不能直接寫輸出到控件,因為這是另起的線程,會報錯。log_tb.Dispatcher.BeginInvoke(new Action(() => { log_tb.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") +"-"+message); }));log_tb.Dispatcher.BeginInvoke(new Action(() =>{log_tb.AppendText(Environment.NewLine);}));}在創建界面的時候,就把線程打開,這樣后面添加一項就會自動進行ping,最后實現效果:
一個簡單好用的小工具,就這樣實現了,雖然還有很多不足,但是可以完美解決我目前面臨的問題。
總結
以上是生活随笔為你收集整理的C# WPF网络实时监测客户端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sc.next在java什么意思_sc.
- 下一篇: 新增成功到编制为空bug_36 个JS