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
0
投稿
猜你喜欢
- 本文实例为大家分享了Unity3D生成一段隧道网格的具体代码,供大家参考,具体内容如下一、需求最近有一个需求,生成段隧道的骨架网格。目前想到
- 本文实例讲述了Java实现指定线程执行顺序的三种方式。分享给大家供大家参考,具体如下:方法一:通过共享对象锁加上可见变量来实现。public
- 本文实例为大家分享了Android简单的自定义标题栏,供大家参考,具体内容如下android自定义控件向来都是开发者最头疼的,但是我们要有那
- 本文实例讲述了Android开发实现读取Assets下文件及文件写入存储卡的方法。分享给大家供大家参考,具体如下:调用一个反编译的.so文件
- 本文实例讲述了Java使用原型模式展现每日生活。分享给大家供大家参考,具体如下:一、模式定义用原型实例指定创建对象的种类,并且通过复制这些原
- java.util.NoSuchElementException报错的行数是一个scnner的next,本来和老师讨论了半天没有什么头绪,错
- 1.如图所示,Spring配置文件应该带有是树叶标识,但此处显示的为普通的properties文件2.选择Open Module Setti
- 目录1.启动分为两种方式2.如何测量一个应用的启动时间3.应用启动的流程4.减少应用的启动时间的耗时5.如何设计延迟加载DelayLoad1
- 初步探索首先我们要了解equals方法是什么,hashcode方法是什么。equals方法equals 是java的obejct类的一个方法
- 作为开发人员,掌握开发环境下的调试技巧十分有必要。我们在编写java程序的过程中,经常会遇到各种莫名其妙的问题,为了检测程序是哪里出现问题,
- 1概述众所周知,Java支持平台无关性、安全性和网络移动性。而Java平台由Java虚拟机和Java核心类所构成,它为纯Java程序提供了统
- 本文实例为大家分享了C#图像处理的具体代码,供大家参考,具体内容如下(1)在Form1窗体中的PictureBox1控件中显示通过OpenF
- 本篇和大家分享的是通过maven对springboot中打war包和jar包;war通常来说生成后直接放到tomcat的webapps下面就
- 本文实例为大家分享了C# this关键字的四种用法,供大家参考,具体内容如下用法一 this代表当前实例,用this.显式调用一
- 一、包装类概述Java有8种基本数据类型:整型(byte、short、int、long)、浮点型(float、double)、布尔型bool
- 摘要:这个问题算是老生常谈了,我也是一段时间没弄过了,所以感觉有些忘了,就记录一下。一、后端通过shiro在session中存储数据://
- JVM自带的类加载器:其关系如下:其中,类加载器在加载类的时候是使用了所谓的“父委托”机制。其中,除了根类加载器以外,其他的类加载器都有且只
- 1、lock是可中断锁,而synchronized 不是可中断锁线程A和B都要获取对象O的锁定,假设A获取了对象O锁,B将等待A释放对O的锁
- 自从SEOTcs系统11月份24日更新了一下SEO得分算法以来,一直困扰我的一个问题出现了,java的数据job任务,在执行过程中会经常报以
- 通常C#使用基于XML的配置文件,不过如果有需要的话,比如要兼顾较老的系统,可能还是要用到INI文件。但C#本身并不具备读写INI文件的AP