C#一个网络小程序的逐步实现过程

news2025/7/19 3:15:43

  经常要检测某些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());

  好了,因为使用Task异步编程,界面也不再阻塞和卡顿了,不过运行多少时间不能准确得到,改动一下代码,就是将时间输出定位到任务完成:

            task.ContinueWith((t) =>
            {
                endTime = DateTime.Now;
                listBox1.Items.Add(endTime.ToString());
                listBox1.Items.Add("OK:" + (endTime - startTime).ToString());
            });

  运行时间为1分41秒,界面不卡顿了。

  可是运行仍然是逐个IP地址在ping,根本没有并行计算的效果。虽然使用了Parallel.ForEach,可能是由于线程需要等待导致资源开销过大,那么线程没有被有效地利用。

  这其实与普通的使用线程来做没有什么区别了。

  4、补充

  ⑴ 检测方法:

            string ipAddress = (string)obj;
            TcpClient client = new TcpClient();
            try
            {
                client.Connect(ipAddress, 80);
                //在线
            }
            catch (Exception ex)
            {
                //不在线
            }
            finally
            {
                client.Close();
            }

  引用:

using System.Net.Sockets;

  ⑵ 检测输入的IP地址是否合法:

    IPAddress address;
    if (IPAddress.TryParse(ipAddress, out address))
    {
        // 检查IP地址是否为IPv4地址
        if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
            return true;
    }else{
        return false;
    }

  对于检测计算机在线与否没有好的方法?看那么多的网络小工具,肯定有!

  先完成这个效果,后面再进行优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

传奇服务器容易受到什么攻击,怎么防御攻击?

有兄弟问明杰&#xff0c;说自己打算开服&#xff0c;听说攻击挺多的&#xff0c;就是想先了解一下开传奇用的服务器最容易受到什么类型的攻击&#xff0c;如果遇到了又改怎么防御呢&#xff1f;带着这个问题&#xff0c;明杰跟大家详细的说一下&#xff0c;常见的开区时候遇到…

Max Sum Plus Plus(DP 滚动数组优化)[HDU - 1024]

题目如下&#xff1a; 题目链接 Max Sum Plus Plus 题解 or 思路&#xff1a; 经典的动态规划问题 dp[i][j]dp[i][j]dp[i][j], 前 jjj 个物品&#xff0c; 我们分成题目要求的 iii 组 对于第 jjj 个物品&#xff0c; 我们可以将它分到 第 kkk 组中&#xff0c; 或者分到新的一…

前端八股文——笔试题

目录 前言 一、flex布局手写题目 二、移动端点击事件为什么有延迟&#xff1f;时间多久&#xff1f;如何解决这个问题&#xff1f; 1.meta标签里面content属性&#xff0c;设置禁止缩放。 2.设置默认宽度为浏览器宽度。 3.设置touch-action&#xff1a;manipulation。 4…

Chat-GPT从注册到搬进服务器

首先&#xff0c;我们要明白的一个事实是&#xff0c;不可能免费的成功搞定&#xff0c;得付出10几块得成本&#xff0c;我这个方法满打满算16块钱&#xff08;是不犯错得情况下&#xff0c;实际上我用了30多了&#xff09; 1.10元买个香港的服务器 不一定是香港的&#xff0c…

Day 04-Composition API_ref reactive 函数

1.ref函数 作用: 定义一个响应式的数据&#xff1b; 语法: const xxx ref(initValue) 创建一个包含响应式数据的引用对象&#xff08;reference对象&#xff0c;简称ref对象&#xff09;。 JS中操作数据&#xff1a; xxx.value 模板中读取数据: 不需要.value&#xff0c;直…

永恒之蓝(MS17-010)

目录追溯了解网络IP查找环境条件复现流程445端口使用MSF的永恒之蓝漏洞模块扫描模块攻击模块温馨提醒&#xff1a;纯水文&#xff0c;如果不幸翻到这篇文章&#xff0c;可以立刻关闭&#xff01; 先整理两个学习的链接&#xff08;本文学习第一个&#xff09;&#xff1a; htt…

JDK19都出来了~是时候梳理清楚JDK的各个版本的特性了【JDK17特性讲解】

JDK各个版本特性讲解-JDK17特性 一、JAVA17概述 JDK 16 刚发布半年&#xff08;2021/03/16&#xff09;&#xff0c;JDK 17 又如期而至&#xff08;2021/09/14&#xff09;&#xff0c;这个时间点特殊&#xff0c;蹭苹果发布会的热度&#xff1f;记得当年 JDK 15 的发布也是同天…

Kafka Consumer auto.offset.reset 理解

先来一下 kafka 官网对于 auto.offset.reset 的解释&#xff1a; 上面的描述挺准确的&#xff0c;但如果没有相关背景会感觉很懵逼。网上也有很多文章讲这个东西并给了很多例子&#xff0c;看了之后总感觉没有理解清楚。 先来看一下怎么查看消费者 group 的 offset 情况&…

wpf需求及实现方法 动态创建控件 对数据模板任意对象操作 查找由 DataTemplate 生成的元素 查找由 ControlTemplate 生成的元素

我想实现一个支持多设备同时更新固件的应用。如下图 插入多少个设备就显示多少个进度度。每个进度条上显示对应的串口及进度。 最终实现演示如下&#xff1a; public MainWindow(){InitializeComponent();List<DownloadProgress> test new List<DownloadProgress>…

文件系统与文件系统管理以及RAID技术的思想

文件与文件系统FCB&#xff08;文件控制块&#xff09;文件是什么&#xff1f;文件是对 磁盘的抽象所谓文件 是指 一组带标识&#xff08;标识即为文件名&#xff09;的、在逻辑上有完整意义的信息项的序列。信息项&#xff1a;构成文件内容的基本单位&#xff08;单个…

AUTOSAR开发

综述 本文档主要描述了VP项目MCU芯片TC297的AUTOSAR方案。MCU的基础软件由AUTOSAR软件实现&#xff0c;AUTOSAR可简易理解为如下层次。 MCU芯片驱动层&#xff1a;MCU芯片的抽象层&#xff0c;目的是将各类MCU芯片进行抽象&#xff0c;向上统一接口&#xff0c;隔离其他层次软件…

自动控制原理笔记-改善性能的措施-高阶系统动态性能

目录 改善性能的措施&#xff1a; 两种改善二阶系统动态性能的措施&#xff1a; &#xff08;1&#xff09;测速反馈——增加阻尼 &#xff08;2&#xff09;比例微分——提前控制 改善系统性能方法对比&#xff1a;​ 两种改善性能方法的对比&#xff1a; 高阶系统动态性…

vscode插件开发入门案例-一键删除js文件中的某个函数

vscode插件开发入门案例-一键删除js文件中的某个函数vscode插件开发入门案例-一键删除js文件中的某个函数demo介绍准备工作插件开发package.json介绍extension.ts调试插件插件打包插件安装插件发布vscode应用市场vscode插件开发入门案例-一键删除js文件中的某个函数 代码仓库地…

数据分析之excel和finebi报表可视化对比

当我们拿到数据&#xff0c;想对数据实现可视化报表设计。第一步就是要了解什么是数据可视化分析&#xff0c;且数据可视化分析的方法有什么&#xff1f;而且当我们拿到excel表格的数据&#xff0c;第一个想法是excel表格自身实现报表数据可视化&#xff0c;除了用excel本身实现…

微信小程序 | 小程序组件化开发

&#x1f5a5;️ 微信小程序 专栏&#xff1a;小程序组件化开发 &#x1f9d1;‍&#x1f4bc; 个人简介&#xff1a;一个不甘平庸的平凡人&#x1f36c; ✨ 个人主页&#xff1a;CoderHing的个人主页 &#x1f340; 格言: ☀️ 路漫漫其修远兮,吾将上下而求索☀️ &#x1f44…

梦想绽放CEO熊文:停产单一VR产品,VST将成为VR行业标配

很久没在北京参加线下活动了&#xff0c;真不容易。今天奇遇VR正式发布了消费级双目全彩VST VR设备&#xff1a;奇遇Dream MIX。会后&#xff0c;我还参加了梦想绽放CEO熊文的群访&#xff0c;从中了解到更多消息。 奇遇Dream MIX 关于奇遇Dream MIX这款产品&#xff0c;我开始…

【苹果iMessage相册推信息推】那些新功效理当可以或许压倒您。保护用户隐私是苹果的起点之一

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

如何从小白起步成为百万博主|配音运营工具必不可少

从新手做短视频&#xff0c;无论你是抖音还是快手&#xff0c;掌握一些视频运营工具&#xff0c;能让我们日常工作事半功倍以下是我做短视频三年来&#xff0c;一直都在使用的工具&#xff0c;从视频素材剪辑软件音效配音&#xff0c;满足了我日常运营的需求&#xff0c;新手也…

Windows Defense Mechanism - Part 1

Overview If I’m a long-time CTF player (or HackTheBox lab machine player), things are gonna go a little off when I’m put into a real world scenario - meaning that, when facing a well defended Windows machine. This article will summarize the main Window…

基于Java(Struts2 框架)+Mysql实现(Web)学生成绩管理系统【100010053】

学生成绩信息管理系统 Summary JavaWeb 课程设计作品。类似学校的教务管理系统&#xff0c;实现了其中的部分功能&#xff0c;包括学生的增删改查&#xff0c;成绩的增删改查等。 Note 关于数据库 数据库名称&#xff1a;smxy_class字符集&#xff1a;UTF-8先建立数据库&am…