C#实现网络小程序的步骤详解
作者:dawn 时间:2023-08-17 18:16:37
经常要检测某些IP地址范围段的计算机是否在线。
有很多的方法,比如进入到网关的交换机上去查询、使用现成的工具或者编写一个简单的DOS脚本等等,这些都比较容易实现。
现在使用C#来完成。
1、简单上手
公用函数:
public static long IPToLong(string ip)
{
//将IP地址转换为长整数
string[] ipBytes = ip.Split('.');
long ipLong = 0;
ipLong += long.Parse(ipBytes[0]) * 256 * 256 * 256;
ipLong += long.Parse(ipBytes[1]) * 256 * 256;
ipLong += long.Parse(ipBytes[2]) * 256;
ipLong += long.Parse(ipBytes[3]);
return ipLong;
}
public static string LongToIP(long ip)
{
//将长整数IP地址转换为实际的IP地址
long ipLong = ip;
string ipString = string.Empty;
ipString += ipLong / 256 / 256 / 256 + ".";
ipLong = ipLong % (256 * 256 * 256);
ipString += ipLong / 256 / 256 + ".";
ipLong = ipLong % (256 * 256);
ipString += ipLong / 256 + ".";
ipLong = ipLong % 256;
ipString += ipLong;
return ipString;
}
点击【检测】按钮:
DateTime startTime, endTime;
startTime= DateTime.Now;
listBox1.Items.Add(startTime.ToString());
string startIP = textBox1.Text;
string endIP = textBox2.Text;
// 将起始IP地址和结束IP地址转换为长整数
long startIPLong = IPToLong(startIP);
long endIPLong = IPToLong(endIP);
Ping ping = new Ping();
// 遍历IP地址范围
for (long i = startIPLong; i <= endIPLong; i++)
{
// 将整数转换为IP地址
string ip = LongToIP(i);
// 输出
PingReply pingReply = ping.Send(ip);
if (pingReply.Status == IPStatus.Success)
{
listBox1.Items.Add( ip + "=>计算机在线");
}
else
{
listBox1.Items.Add(ip);
}
}
endTime = DateTime.Now;
listBox1.Items.Add(endTime.ToString());
listBox1.Items.Add("OK:" + (endTime - startTime).ToString());
执行时没有问题的,可以出来结果,问题是界面卡顿了。
执行的时间也很长,执行需要1分21秒。
这个结果不能接受,需要对程序加以改进。
2、使用并行计算
不需要改动公用代码,只需要改动检测部分。
Dictionary<string, string> ipResults = new Dictionary<string, string>();
DateTime startTime, endTime;
startTime = DateTime.Now;
listBox1.Items.Add(startTime.ToString());
string startIP = textBox1.Text;
string endIP = textBox2.Text;
// 将起始IP地址和结束IP地址转换为整数
long startIPLong = IPToLong(startIP);
long endIPLong = IPToLong(endIP);
// 创建一个可以存储IP地址的List
List<string> ipList = new List<string>();
for (long i = startIPLong; i <= endIPLong; i++)
{
// 将整数转换为IP地址
string ip = LongToIP(i);
ipList.Add(ip);
ipResults.Add(ip,"");
listBox1.Items.Add(ip);
}
// 开启并行计算
Parallel.ForEach(ipList, (ip) =>
{
// 创建一个新的Ping类
Ping pingSender = new Ping();
// 发送一个Ping请求
var reply = pingSender.Send(ip);
// 如果返回的状态是Success,则IP地址在线
if (reply.Status == IPStatus.Success)
{
ipResults[ip] = "在线";
ChangeIPStatus(ip,"在线");
}
else
{
ipResults[ip] = "NO";
ChangeIPStatus(ip, "NO");
}
});
endTime = DateTime.Now;
listBox1.Items.Add(endTime.ToString());
listBox1.Items.Add("OK:" + (endTime - startTime).ToString());
增加一个公用函数:
public void ChangeIPStatus(string ip,string S1)
{
// 定位到listbox中记录并更改IP是否在线
int index = listBox1.Items.IndexOf(ip);
listBox1.Items[index] = ip+""+S1;
}
出现问题:
⑴提示“C#线程间操作无效:从不是创建控件“textbox1”的线程访问它”,这个就简单设置Control.CheckForIllegalCrossThreadCalls=false即可解决;
⑵提示“listbox1包含的项太多”,这个是不是与并行计算开启的线程太多有关?考虑到本机是8核,保守一点,修改参数
Parallel.ForEach(ipList, new ParallelOptions() { MaxDegreeOfParallelism = MaxDegreeOfParallelism = Environment.ProcessorCount }, (ip) =>
{
//执行代码
}
程序可以正常运行了。
⑶界面依然阻塞,但用时更多了。
去ping255个地址,竟然用了12分32秒!!!这个真是不可忍受,最关键没有界面交互,这太不用户友好了!
3、添加异步编程
Dictionary<string, string> ipResults = new Dictionary<string, string>();
DateTime startTime, endTime;
startTime = DateTime.Now;
listBox1.Items.Add(startTime.ToString());
string startIP = textBox1.Text;
string endIP = textBox2.Text;
// 将起始IP地址和结束IP地址转换为整数
long startIPLong = IPToLong(startIP);
long endIPLong = IPToLong(endIP);
// 创建一个可以存储IP地址的List
List<string> ipList = new List<string>();
for (long i = startIPLong; i <= endIPLong; i++)
{
// 将整数转换为IP地址
string ip = LongToIP(i);
ipList.Add(ip);
ipResults.Add(ip,"");
listBox1.Items.Add(ip);
}
Task task = new Task(() =>
{
// 创建一个多线程
Parallel.ForEach(ipList, new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount }, (ip) =>
{
// 创建一个新的Ping类
Ping pingSender = new Ping();
// 发送一个Ping请求
var reply = pingSender.Send(ip);
if (reply.Status == IPStatus.Success)
{
listBox1.Invoke(new Action(() =>
{
int index = listBox1.Items.IndexOf(ip);
listBox1.Items[index] = ip + "" + "在线";
}));
}
else
{
listBox1.Invoke(new Action(() =>
{
int index = listBox1.Items.IndexOf(ip);
listBox1.Items[index] = ip + "" + "NO";
}));
}
});
});
task.Start();
Task.WaitAll();
endTime = DateTime.Now;
listBox1.Items.Add(endTime.ToString());
listBox1.Items.Add("OK:" + (endTime - startTime).ToString());
来源:https://blog.csdn.net/dawn0718/article/details/128449738
标签:C#,网络,小程序
![](/images/zang.png)
![](/images/jiucuo.png)
猜你喜欢
Struts2下拉框实例解析
2021-09-16 16:29:59
![](https://img.aspxhome.com/file/2023/9/61399_0s.jpg)
Mockito mock Kotlin Object类方法报错解决方法
2022-03-10 15:23:37
java对象类型转换和多态性(实例讲解)
2023-06-23 16:33:53
![](https://img.aspxhome.com/file/2023/6/84206_0s.jpg)
Java中Range函数的简单介绍
2023-10-18 05:33:35
![](https://img.aspxhome.com/file/2023/0/66970_0s.png)
IDEA解决src和resource下创建多级目录的操作
2023-03-24 07:05:37
![](https://img.aspxhome.com/file/2023/0/63690_0s.jpg)
SpringBoot处理接口幂等性的两种方法详解
2021-12-23 10:32:32
Android返回键功能的实现方法
2021-10-01 12:54:53
Android实现通讯录效果——获取手机号码和姓名
2021-10-25 11:53:59
![](https://img.aspxhome.com/file/2023/1/118961_0s.gif)
Android中初始化Codec2的具体流程
2023-08-27 21:30:32
![](https://img.aspxhome.com/file/2023/0/137580_0s.jpg)
基于Java实现Json文件转换为Excel文件
2022-08-04 23:53:15
springboot前端传参date类型后台处理的方式
2023-04-12 16:47:35
![](https://img.aspxhome.com/file/2023/1/85941_0s.png)
C#编程获取IP地址的方法示例
2023-06-16 21:18:20
Java实现24点小游戏
2023-07-26 07:34:55
![](https://img.aspxhome.com/file/2023/6/63336_0s.png)
Swagger2配置方式(解决404报错)
2022-08-30 17:21:13
![](https://img.aspxhome.com/file/2023/0/63660_0s.png)
Android图片加载库Glide用法
2023-08-11 10:12:01
![](https://img.aspxhome.com/file/2023/1/138561_0s.jpg)
Java 爬虫工具Jsoup详解
2022-04-11 03:46:16
深入理解Javascript中的this关键字
2022-03-08 16:52:25
如何从eureka获取服务的ip和端口号进行Http的调用
2021-07-05 05:28:13
基于java实现简单发红包功能
2023-08-09 17:06:40
![](https://img.aspxhome.com/file/2023/9/72559_0s.jpg)
关于LinkedList集合对元素进行增查删操作
2022-09-23 11:48:45
![](https://img.aspxhome.com/file/2023/5/66535_0s.png)