C#实现网络小程序的步骤详解
作者:dawn 发布时间:2023-08-17 18:16:37
标签:C#,网络,小程序
经常要检测某些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


猜你喜欢
- 这次是列表滑动删除的第三波,仿微信的列表滑动删除。先上个效果图: 前面的文章里面说过开源框架SwipeListView
- 前言我们经常会被问到这么一个问题:SpringBoot相对于spring有哪些优势呢?其中有一条答案就是SpringBoot自动注入。那么自
- 本文包含3种隐藏顶部状态栏及标题栏和一种隐藏Android 4.0平板底部状态栏的方法,分享给大家供大家参考,具体内容如下方法一public
- 前言公司的邮件系统用的是 * 的 Lotus notes, 你敢信?最近要实现一个功能,邮件提醒功能,就是通过自动发送提醒邮件 前
- 前言在我们的工作中,经常会遇到需要在普通类中使用放在Spring容器中的类的情况。最常见的情况大概就是有一个类他的属性的是通过spring的
- 看到软二的群里,某童鞋发了个自己的java大作业的截图,类似于一个图片,处理后,根据不同的灰度值,填充不同的字符。故,我也用C#来写个玩玩~
- 一、实现效果图二、实现代码1.自定义viewpackage com.czhappy.showintroduce.view;import an
- 这篇文章算是对整个引导界面开发专题的一个终结了吧,个人觉得大部分的引导界面基本上都是千篇一律的,只要熟练掌握了一个,基本上也就没什么好说的了
- 1. InputStream -> byte[]引入 apache.commons.is 包import org.apache.com
- Java实现驼峰、下划线互转1.使用 Guava 实现先引入相关依赖<dependency> <
- 最近项目中新增的功能,需要对手机号、姓名、身份证号等一些信息进行验证,最好的方法是通过正则表达式来验证,网上查了一些资料,写了这几个工具方法
- 本文是Spring Security系列中的一篇。在上一篇文章中,我们通过实现UserDetailsService和UserDetails接
- 学会了技术就要使用,否则很容易忘记,因为自然界压根就不存在什么代码、变量之类的玩意,这都是一些和生活常识格格不入的东西。只能多用多练,形成肌
- MyBatis介绍MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software
- 在本文中,我们将看到几个关于如何在Java 8中对List进行排序的示例。1.按字母顺序排序字符串列表List<String>
- 实践过程效果代码public partial class Form1 : Form{ public Form1()
- 第1部分 TreeSet介绍TreeSet简介TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。它继承于AbstractSe
- 什么是WebSocket WebSocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket使得客户端和服务器之间
- MyBatis @MapKey的妙用背景在实际开发中,有一些场景需要我们返回主键或者唯一键为Key、Entity为Value的Map集合,如
- SpringBoot访问html和js等静态资源配置把静态资源放到resources/static下,这是springboot静态资源默认访