当前位置: 首页 > news >正文

C#实现多线程局域网扫描器的思路与具体代码

C#实现多线程局域网扫描器的思路与具体代码

思路:

  1. 获取局域网内所有 IP 地址
  2. 遍历所有 IP 地址,使用 Ping 命令测试主机是否在线
  3. 如果主机在线,则扫描主机上的所有端口,确定哪些端口是开放的
  4. 输出扫描结果

在上述过程中,第 2 步和第 3 步都可以使用多线程来加速。具体来说,可以将 IP 地址分成若干段,每个线程负责扫描一段 IP 地址。对于每个 IP 地址,也可以启动一个线程来扫描其端口。

具体代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading;namespace LANScanner
{class Program{// 扫描参数static int numThreads = 100;static int timeout = 100;static void Main(string[] args){// 获取本地 IP 地址和子网掩码IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName());IPAddress subnetMask = null;foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces()){IPInterfaceProperties properties = adapter.GetIPProperties();foreach (UnicastIPAddressInformation addressInfo in properties.UnicastAddresses){if (addressInfo.Address.AddressFamily == AddressFamily.InterNetwork){subnetMask = addressInfo.IPv4Mask;break;}}if (subnetMask != null){break;}}// 计算子网地址和广播地址IPAddress subnetAddress = GetSubnetAddress(addresses[0], subnetMask);IPAddress broadcastAddress = GetBroadcastAddress(addresses[0], subnetMask);// 创建线程池并开始扫描List<WaitHandle> handles = new List<WaitHandle>();ThreadPool.SetMinThreads(numThreads, numThreads);for (int i = 1; i <= 254; i++){IPAddress ip = GetIPAddress(subnetAddress, i);handles.Add(new ManualResetEvent(false));ThreadPool.QueueUserWorkItem(PingHost, new object[] { ip, handles.Last() });}WaitHandle.WaitAll(handles.ToArray());Console.WriteLine("Scanning complete.");Console.ReadLine();}static void PingHost(object args){// 解析参数object[] parameters = (object[])args;IPAddress ip = (IPAddress)parameters[0];ManualResetEvent handle = (ManualResetEvent)parameters[1];// 测试主机是否在线Ping ping = new Ping();PingReply reply = ping.Send(ip, timeout);if (reply.Status == IPStatus.Success){Console.WriteLine("Host {0} is online.", ip);// 扫描主机上的端口List<WaitHandle> handles = new List<WaitHandle>();for (int port = 1; port <= 65535; port++){handles.Add(new ManualResetEvent(false));ThreadPool.QueueUserWorkItem(CheckPort, new object[] { ip, port, handles.Last() });}WaitHandle.WaitAll(handles.ToArray());}// 通知主线程完成handle.Set();}static void CheckPort(object args){// 解析参数object[] parameters = (object[])args;IPAddress ip = (IPAddress)parameters[0];int port = (int)parameters[1];ManualResetEvent handle = (ManualResetEvent)parameters[2];// 尝试连接端口try{using (TcpClient client = new TcpClient()){client.Connect(ip, port);Console.WriteLine("Port {0} is open on host {1}.", port, ip);}}catch (Exception){// 端口未打开}// 通知主线程完成handle.Set();}static IPAddress GetSubnetAddress(IPAddress address, IPAddress subnetMask){byte[] addressBytes = address.GetAddressBytes();byte[] maskBytes = subnetMask.GetAddressBytes();byte[] subnetBytes = new byte[4];for (int i = 0; i < 4; i++){subnetBytes[i] = (byte)(addressBytes[i] & maskBytes[i]);}return new IPAddress(subnetBytes);}static IPAddress GetBroadcastAddress(IPAddress address, IPAddress subnetMask){byte[] addressBytes = address.GetAddressBytes();byte[] maskBytes = subnetMask.GetAddressBytes();byte[] broadcastBytes = new byte[4];for (int i = 0; i < 4; i++){broadcastBytes[i] = (byte)(addressBytes[i] | ~maskBytes[i]);}return new IPAddress(broadcastBytes);}static IPAddress GetIPAddress(IPAddress subnetAddress, int host){byte[] subnetBytes = subnetAddress.GetAddressBytes();byte[] hostBytes = new byte[4];hostBytes[3] = (byte)host;byte[] ipBytes = new byte[4];for (int i = 0; i < 4; i++){ipBytes[i] = (byte)(subnetBytes[i] | hostBytes[i]);}return new IPAddress(ipBytes);}}
}

上述代码实现了一个简单的多线程局域网扫描器,支持 Ping 主机和扫描主机端口,并输出扫描结果。需要注意的是,在实际应用中,可能需要对输入进行严格的验证和过滤,以确保系统安全。

同时,在使用多线程和异步 I/O 操作时,也需要注意程序的正确性和健壮性。如果不正确地使用这些技术,可能会导致程序出现各种问题,例如竞态条件和死锁。因此,在使用这些技术时,请务必小心并仔细测试程序。

要解决错误“WaitHandles的数量必须小于或等于64”,需要将句柄列表拆分为更小的块,并使用WaitAll分别等待每个块。例如,你可以将句柄列表分成4个块,每个块25个句柄,然后分别等待每个块:

List<WaitHandle>[] handleChunks = new List<WaitHandle>[4];
for (int i = 0; i < handleChunks.Length; i++)
{handleChunks[i] = new List<WaitHandle>();
}
for (int i = 1; i <= 254; i++)
{// ...int chunkIndex = (i - 1) % handleChunks.Length;handleChunks[chunkIndex].Add(new ManualResetEvent(false));ThreadPool.QueueUserWorkItem(PingHost, new object[] { ip, handleChunks[chunkIndex].Last() });
}
for (int i = 0; i < handleChunks.Length; i++)
{WaitHandle.WaitAll(handleChunks[i].ToArray());
}

相关文章:

C#实现多线程局域网扫描器的思路与具体代码

C#实现多线程局域网扫描器的思路与具体代码 思路&#xff1a; 获取局域网内所有 IP 地址遍历所有 IP 地址&#xff0c;使用 Ping 命令测试主机是否在线如果主机在线&#xff0c;则扫描主机上的所有端口&#xff0c;确定哪些端口是开放的输出扫描结果 在上述过程中&#xff0…...

Redis秒杀:一人一单问题及初步解决

优惠券秒杀一人一单 前言一、需求以及之前存在的问题二、增加一人一单逻辑1.初步代码2.封装一人一单逻辑3.控制锁的粒度 三、事务控制问题四、总结 前言 跟随黑马虎哥学习redis&#xff1a; 这是我认为b站上最好的redis教程&#xff0c;各方面讲解透彻&#xff0c;知识点覆盖…...

python 数据分析面试题:求分组排第n名的记录数据

近期面试遇到一个面试题&#xff0c;分享给大家。 文中会提供详细的解题思路以及问题延伸 一、面试题 面试题&#xff1a;输出各学科总分第一名的学员姓名、年龄、分数数据&#xff1a; class_a {name: [学员1, 学员2, 学员3, 学员4,学员5],age: [23, 24, 26, 27,25],course…...

eclipse常用快捷键

Eclipse常用快捷键 补全代码的声明&#xff1a;alt /快速修复: ctrl 1批量导包&#xff1a;ctrl shift o使用单行注释&#xff1a;ctrl /使用多行注释&#xff1a; ctrl shift /取消多行注释&#xff1a;ctrl shift \复制指定行的代码&#xff1a;ctrl alt down 或…...

什么是OCR?OCR技术详解

光学字符识别(Optical Character Recognition)简称为“OCR”。ORC是指对包含文本资料的图像文件进行分析识别处理&#xff0c;获取文字及版面信息的技术。 一般包括以下几个过程&#xff1a; 1.图像输入 针对不同格式的图像&#xff0c;有着不同的存储格式和压缩方式。目前&…...

【大模型】开源且可商用的大模型通义千问-7B(Qwen-7B)来了

【大模型】开源且可商用的大模型通义千问-7B&#xff08;Qwen-7B&#xff09;来了 新闻通义千问 - 7B 介绍评测表现快速使用环境要求安装相关的依赖库推荐安装flash-attention来提高你的运行效率以及降低显存占用使用 Transformers 运行模型使用 ModelScope 运行模型 量化长文本…...

SQL分类及通用语法数据类型

一、SQL分类 DDL: 数据定义语言&#xff0c;用来定义数据库对象&#xff08;数据库、表、字段&#xff09;DML: 数据操作语言&#xff0c;用来对数据库表中的数据进行增删改DQL: 数据查询语言&#xff0c;用来查询数据库中表的记录DCL: 数据控制语言&#xff0c;用来创建数据库…...

亿欧智库:2023中国功效型护肤产品成分解析研究报告(附下载

关于报告的所有内容&#xff0c;公众【营销人星球】获取下载查看 核心观点 消费端&#xff1a;“纯净美妆〞概念火热&#xff0c;消费驱动因素向成分来源硬核转变 新冠疫情过后&#xff0c;消费者对于生活健康&#xff1a;自然&#xff0c;可持续的关注度持续上升。在消费者…...

Kubernetes高可用集群二进制部署(一)主机准备和负载均衡器安装

Kubernetes概述 使用kubeadm快速部署一个k8s集群 Kubernetes高可用集群二进制部署&#xff08;一&#xff09;主机准备和负载均衡器安装 Kubernetes高可用集群二进制部署&#xff08;二&#xff09;ETCD集群部署 Kubernetes高可用集群二进制部署&#xff08;三&#xff09;部署…...

python与深度学习(十二):CNN和猫狗大战二

目录 1. 说明2. 猫狗大战的CNN模型测试2.1 导入相关库2.2 加载模型2.3 设置保存图片的路径2.4 加载图片2.5 图片预处理2.6 对图片进行预测2.7 显示图片 3. 完整代码和显示结果4. 多张图片进行测试的完整代码以及结果 1. 说明 本篇文章是对上篇文章猫狗大战训练的模型进行测试。…...

React(1)——快速入门

目录 一、React背景简介 ❤️ 官网和资料 &#x1f4da; 介绍描述 &#x1f427; React的特点 &#x1f528; React高效的原因 &#x1f64f;&#x1f3fb; 二、React的基本使用 &#x1f4bb; 三、React JSX&#xff08;JSX:JavaScript XML&#xff09;&#x1f4e6; …...

【论文】【生成对抗网络五】Wasserstein GAN (WGAN)

【题目、作者】&#xff1a; 紫色&#xff1a;要解决的问题或发现的问题 红色&#xff1a;重点内容 棕色&#xff1a;关联知识&#xff0c;名称 绿色&#xff1a;了解内容&#xff0c;说明内容 论文地址&#xff1a; 论文下载 本篇文章仅为原文翻译&#xff0c;仅作参考。…...

学习率Learn_rate是什么(深度学习)

学习率是指在训练神经网络时用于调整参数的步进大小&#xff0c;它决定了每次梯度更新时参数的调整程度。学习率的选择直接关系到模型的性能和训练过程的效果。 学习率变化可能带来的影响&#xff1a; 收敛速度&#xff1a;较高的学习率可以加快模型的收敛速度&#xff0c;因为…...

webpack基础知识五:说说Loader和Plugin的区别?编写Loader,Plugin的思路?

一、区别 前面两节我们有提到Loader与Plugin对应的概念&#xff0c;先来回顾下 loader 是文件加载器&#xff0c;能够加载资源文件&#xff0c;并对这些文件进行一些处理&#xff0c;诸如编译、压缩等&#xff0c;最终一起打包到指定的文件中plugin 赋予了 webpack 各种灵活的…...

AI大模型之花,绽放在鸿蒙沃土

随着生成式AI日益火爆&#xff0c;大语言模型能力引发了越来越多对于智慧语音助手的期待。 我们相信&#xff0c;AI大模型能力加持下的智慧语音助手一定会很快落地&#xff0c;这个预判不仅来自对AI大模型的观察&#xff0c;更来自对鸿蒙的了解。鸿蒙一定会很快升级大模型能力&…...

[JAVAee]锁策略

目录 乐观锁与悲观锁 乐观锁 乐观锁的冲突检测 悲观锁 读锁与写锁 重量级锁与轻量级锁 重量级锁 轻量级锁 自旋锁 公平锁与非公平锁 可重入锁与不可重入锁 乐观锁与悲观锁 乐观锁 在乐观锁中,假设数据并不会发生冲突,在正式提交数据时会对数据进行冲突检测,如果发…...

uni-app-使用tkiTree组件实现树形结构选择

前言 在实际开发中我们经常遇见树结构-比如楼层区域-组织架构-部门岗位-系统类型等情况 往往需要把这个树结构当成条件来查询数据&#xff0c;在PC端可以使用Tree&#xff0c;table&#xff0c;Treeselect等组件展示 在uni-app的内置组件中似乎没有提供这样组件来展示&#x…...

SQL-每日一题【1179. 重新格式化部门表】

题目 部门表 Department&#xff1a; 编写一个 SQL 查询来重新格式化表&#xff0c;使得新的表中有一个部门 id 列和一些对应 每个月 的收入&#xff08;revenue&#xff09;列。 查询结果格式如下面的示例所示&#xff1a; 解题思路 1.题目要求我们重新格式化表&#xff0c;…...

GO语言语法结构

GO语言结构 包声明引入包函数变量语句 && 表达式注释 package main import "fmt" func main() {fmt.Println("Hello,World!") } 如这段代码块根据上面的语法结构进行逐行解释 第一行的 package main 是定义一个包名&#xff0c;必须在源文件…...

C++学习——模板

目录 &#x1f349;一&#xff1a;什么是模板 &#x1f34e;二&#xff1a;普通模板的定义 &#x1f34d;三&#xff1a;类模板的定义 &#x1f34c;四&#xff1a;模板的实例化 &#x1f347;1.当普通模板定义存在可修改返回值产生的分歧 &#x1f348;2&#xff1a;类模板实例…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

3-11单元格区域边界定位(End属性)学习笔记

返回一个Range 对象&#xff0c;只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意&#xff1a;它移动的位置必须是相连的有内容的单元格…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...