当前位置: 首页 > 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;类模板实例…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...

【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?

FTP&#xff08;File Transfer Protocol&#xff09;本身是一个基于 TCP 的协议&#xff0c;理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况&#xff0c;主要原因包括&#xff1a; ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...

深入理解 React 样式方案

React 的样式方案较多,在应用开发初期,开发者需要根据项目业务具体情况选择对应样式方案。React 样式方案主要有: 1. 内联样式 2. module css 3. css in js 4. tailwind css 这些方案中,均有各自的优势和缺点。 1. 方案优劣势 1. 内联样式: 简单直观,适合动态样式和…...