实习第12天 多线程监控网络软件,解析XML

关于微软的产品,可前往msdn论坛找答案

https://social.msdn.microsoft.com/Forums/zh-CN/home

利用winform,C#做了监控网络软件用到了网络、多线程、XML的知识,

检测所给的ip地址,连接是否正常,不正常的写入数据库日志文件,

ip数据利用xml存储可以动态配置。

 参考资料:
 c#读取XML http://www.cnblogs.com/a1656344531/archive/2012/11/28/2792863.html

关于DataTable内部索引已损坏的解决办法 

C#中WinForm程序退出方法技巧总结 http://www.jb51.net/article/58816.htm  

强制退出WinForm程序之Application.Exit和Environment.Eixt

错误:在VS上点击停止调试后,系统蓝屏了。

原因:VS上的停止调试,应该相当于任务管理系统的强制关闭作用,

在我多线程任务中读取或修改资源的时候被强制关闭,引发内存出错,

而电脑重启后线程操作的写入文件数据出现了一大堆奇怪的符号

解决方案:

我们关闭的时候点击程序里的关闭窗口,

关闭事件,先关闭所有对象(线程),再把窗体资源释放。

https://msdn.microsoft.com/en-us/library/system.windows.forms.form.close.aspx

When a form is closed, all resources created within the object are closed and the form is disposed. You can prevent the closing of a form at run time by handling theClosing event and setting the Cancel property of the CancelEventArgs passed as a parameter to your event handler. If the form you are closing is the startup form of your application, your application ends.

The two conditions when a form is not disposed on Close is when (1) it is part of a multiple-document interface (MDI) application, and the form is not visible; and (2) you have displayed the form using ShowDialog. In these cases, you will need to call Dispose manually to mark all of the form's controls for garbage collection.

效果图

Form.cs 主界面逻辑

  1 using System;
  2 using System.Collections.Generic;
  3 using System.ComponentModel;
  4 using System.Data;
  5 using System.Drawing;
  6 using System.Linq;
  7 using System.Text;
  8 using System.Windows.Forms;
  9 using System.Threading;
 10 using System.Xml;
 11 using System.Xml.Linq;
 12 using networkListener;
 13 
 14 namespace WindowsFormsApplication1
 15 {
 16     public partial class Form1 : Form
 17     {
 18         //循坏秒数
 19         static int scanSecond = 20;
 20 
 21         //存储ip的数组
 22         public static String[] ips = null;
 23 
 24         //每个线程处理ip数目
 25         public static int dealNum = 10;
 26 
 27         //ip信息DataTable
 28         DataTable infoDt = null;
 29 
 30         DateTime beginTime ;
 31 
 32         DateTime endTime ;
 33 
 34         LogDAL logDAL ;
 35 
 36         List<NetThread> threadList;
 37 
 38         public Form1()
 39         {
 40             InitializeComponent();
 41 
 42             logDAL = new LogDAL();
 43 
 44             threadList = new List<NetThread>();
 45 
 46             //ip信息表初始化
 47             infoDt = new DataTable();
 48             infoDt.Columns.Add(new DataColumn("名字"));
 49             infoDt.Columns.Add(new DataColumn("ip地址"));
 50 
 51             //数据初始化
 52             threadNumText.Text = dealNum + "";
 53             scanSecondText.Text = scanSecond + "";
 54 
 55             //timer初始化
 56             timer1.Interval = scanSecond * 1000;
 57             timer1.Stop();
 58         }
 59 
 60         /// <summary>
 61         /// 准备需要迭代ip数据
 62         /// </summary>
 63         private  void preparaData()
 64         {
 65             showMsg("读取ip.xml文件中!");
 66             //读取ip.xml文件
 67             XElement xe = XElement.Load("ip.xml");
 68             //@"....ip.xml" 对于输出目录  
 69 
 70             //直接找到元素为ip的这个结点,然后遍历读取所有的结果.
 71             IEnumerable<XElement> elements = from adress in xe.Elements("ip")
 72                                              select adress;
 73             showInfo(elements);
 74 
 75         }
 76 
 77         /// <summary>
 78         /// 迭代XML中所有ip节点
 79         /// </summary>
 80         /// <param name="elements">ip节点集合</param>
 81         private  void showInfo(IEnumerable<XElement> elements)
 82         {
 83             String name;
 84             String ip;
 85             int size = elements.Count();
 86             ips = new String[size];
 87 
 88             infoDt.Clear();
 89 
 90             //迭代出节点的数据
 91             int i = 0;
 92             foreach (var ele in elements)
 93             {
 94                 name = ele.Element("name").Value;
 95                 ip = ele.Element("adress").Value;
 96                 infoDt.Rows.Add(new object[] { name, ip });  
 97                 ips[i] = ip;
 98                 i++;
 99             }
100 
101             //数据绑定到表
102             infoDataGrid.DataSource = infoDt;
103 
104         }
105 
106         /// <summary>
107         /// 刷新日志文件读取
108         /// </summary>
109         private void refreshLog()
110         {
111 
112             DataSet ds = logDAL.GetList("", "LOG_NETLISTEN", "ROWNUM <= 200", "CREATE_TIME DESC");
113             DataTable dt=ds.Tables[0];
114             //数据绑定到表
115             logDataGrid.DataSource = dt;
116             logDataGrid.Columns[3].DefaultCellStyle.Format = "yyyy-MM-dd HH:mm:ss ";
117             logDataGrid.Refresh();
118         }
119 
120         /// <summary>
121         /// 启动按钮时间
122         /// </summary>
123         /// <param name="sender"></param>
124         /// <param name="e"></param>
125         private void startButton_Click(object sender, EventArgs e)
126         {
127               showMsg("程序成功启动!");
128               startButton.Enabled = false;
129               modifyButton.Enabled = false;
130 
131             //准备ip数据
132               preparaData();
133               showMsg("ip数初始化完毕!");
134 
135               netScan();
136               timer1.Start();
137         }
138 
139         /// <summary>
140         /// 添加消息
141         /// </summary>
142         /// <param name="message">消息</param>
143         public  void showMsg(String message) {
144             this.msgTextBox.AppendText(message + System.Environment.NewLine);
145         }
146 
147         /// <summary>
148         /// timer每隔一段时间自动调用
149         /// </summary>
150         /// <param name="sender"></param>
151         /// <param name="e"></param>
152         private void timer1_Tick(object sender, EventArgs e)
153         {
154             netScan();
155         }
156 
157         /// <summary>
158         ///  多线程监控网络
159         /// </summary>
160         private void netScan() {
161             showMsg("多线程监控网络开始");
162             beginTime = System.DateTime.Now;
163             //启动网络监听多线程
164             for (int i = 0; i < ips.Length; i += dealNum)
165             {
166                 new NetThread(i).start();
167             }
168 
169             endTime = System.DateTime.Now;
170             
171             showMsg("耗时:"+(endTime-beginTime));
172             showMsg("多线程监控网络结束");
173 
174             refreshLog();//刷新日志文件
175             showMsg("更新日志文件");
176             showMsg("=====================");
177         }
178 
179         private void modifyButton_Click(object sender, EventArgs e)
180         {
181             threadNumText.Text = dealNum + "";
182             scanSecondText.Text = scanSecond + "";
183             dealNum = Convert.ToInt16(threadNumText.Text);
184             scanSecond = Convert.ToInt16(scanSecondText.Text);
185         }
186 
187 
188 
189       }
190  }

LogDAL.cs 操作数据库

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using SysDev.Utility.Data;
 6 using SysDev.Utility.Security;
 7 using System.Configuration;
 8 using System.Data;
 9 
10 namespace WindowsFormsApplication1
11 {
12     class LogDAL
13     {
14         /// <summary>
15         /// 返回本项目默认数据库连接串
16         /// </summary>
17         /// <returns></returns>
18         public string GetDefaultConn()
19         {
20             return Security.Decrypt(ConfigurationManager.AppSettings["NetListenConn"]);
21         }
22 
23         /// <summary>
24         /// 构造主列表SQL语句
25         /// </summary>
26         /// <param name="columnString">显示列</param>
27         /// <param name="filterString">筛选条件</param>
28         /// <param name="orderbyString">排序条件</param>
29         /// <returns>SQL执行语句</returns>
30         private string CreateSqlList(string columnString, string tableName, string filterString, string orderbyString)
31         {
32             StringBuilder cmdText = new StringBuilder();
33             if (columnString == "")
34                 cmdText.Append("select * from " + tableName);     //默认全显示 sys_binding
35             else
36                 cmdText.Append("select " + columnString + " from " + tableName + " ");
37 
38             if (filterString.Trim() != "")
39                 cmdText.Append(" where " + filterString);
40 
41             if (orderbyString.Trim() != "")
42                 cmdText.Append(" order by " + orderbyString);
43             else
44                 cmdText.Append(" order by ID");       //默认按主键倒序
45 
46             return cmdText.ToString();
47         }
48 
49         /// <summary>
50         /// 返回数据列表
51         /// </summary>
52         /// <param name="columnString">显示列</param>
53         /// <param name="filterString">筛选条件</param>
54         /// <param name="orderbyString">排序条件</param>
55         /// <returns></returns>
56         public DataSet GetList(string columnString, string tableName, string filterString, string orderbyString)
57         {
58             string sqlString = this.CreateSqlList(columnString, tableName, filterString, orderbyString);
59             return ORAHelper.Query(sqlString, GetDefaultConn());
60         }
61 
62 
63 
64         /// <summary>
65         /// 添加绑定信息
66         /// </summary>
67         /// <param name="sys_id">系统编号</param>
68         /// <param name="oper_no">主工号</param>
69         /// <param name="oper_no_binding">绑定的分工号</param>
70         public void Add(string log_ip, string log_msg)
71         {
72             ORAHelper.ExecuteSql("insert into LOG_NETLISTEN (LOG_ID,SERVER_IP,ERROR_MSG) " +
73                                "values(seq_log.nextval,'" + log_ip + "','" + log_msg + "')", GetDefaultConn());
74         }
75 
76     }
77 }

NetThread.cs 线程逻辑

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 using System.Threading;
 6 using System.Net.NetworkInformation;
 7 using WindowsFormsApplication1;
 8 using System.Data;
 9 using System.Xml;
10 using System.Xml.Linq;
11 
12 namespace networkListener
13 {
14     class NetThread 
15     {
16         //线程
17         Thread thread = null;
18 
19         //ping工具
20         Ping ping = new Ping();
21 
22         //ping响应结果
23         PingReply pingReply = null;
24 
25         //扫描的起始下标 (包含)
26         int beginIndex ;
27 
28         //扫描的终止下标(不包含)
29         int endIndex;
30 
31         LogDAL logDAL;
32 
33         /// <summary>
34         /// NetThread构造方法,用于传入beginIndex
35         /// </summary>
36         /// <param name="beginIndex">线程处理的起始下表</param>
37         public NetThread(int beginIndex) {
38             this.beginIndex = beginIndex;
39             this.endIndex = beginIndex + Form1.dealNum;
40             logDAL = new LogDAL();
41         }
42 
43         /// <summary>
44         /// 线程的主逻辑业务
45         /// </summary>
46         public void run() {
47 
48             //endIndex 大于ip数目时候
49             if (endIndex > Form1.ips.Length)
50             {
51                 endIndex = Form1.ips.Length;
52             }
53 
54              
55             for (int i = beginIndex; i < endIndex; i++)
56             {
57                 //ip响应结果
58                 pingReply = ping.Send(Form1.ips[i]);
59 
60                 //ping的通 
61                 if (pingReply.Status == IPStatus.Success)
62                 {
63                     //success
64                 }
65                 else
66                 {   //fail
67                     logDAL.Add(Form1.ips[i], "" + pingReply.Status);
68                 }
69             }
70 
71         }
72 
73         /// <summary>
74         /// 用于启动线程 
75         /// </summary>
76         public  void start() {
77             if (thread == null) {
78                 thread = new Thread(run);
79             }
80             thread.Start();
81         }
82 
83         public void disposeTest() {
84             thread.DisableComObjectEagerCleanup();
85             if (thread!=null)
86             {
87                 thread = null;
88             }
89         }
90 
91     }
92 }
原文地址:https://www.cnblogs.com/linkarl/p/4726197.html