基于C#实现端口扫描器(单线程和多线程)
目录
- 一、新建项目并设置界面
- 二、单线程实现端口扫描
- 1. 编写代码
- 2. 运行结果
- 三、多线程实现端口扫描
- 1. 编写代码
- 2. 运行结果
- 四、总结
一、新建项目并设置界面 新建项目:
选择Windows窗体项目应用(.Net Framework):
文章图片
设置项目名和路径:
文章图片
新建项目如下:
文章图片
设置界面:
文章图片
将tbShow设置为只读:
文章图片
二、单线程实现端口扫描
1. 编写代码
双击按钮,编写其点击事件:
文章图片
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Scan{public partial class Form1 : Form{//主机地址private string hostAddress; //起始端口private int start; //终止端口private int end; //端口号private int port; //定义线程对象private Thread scanThread; public Form1(){InitializeComponent(); }private void button1_Click_1(object sender, EventArgs e){try{//初始化tbShow.Clear(); lb.Text = "0%"; //获取ip地址和始末端口号hostAddress = tbHost.Text; start = Int32.Parse(tbSPort.Text); end = Int32.Parse(tbEPort.Text); if (decideAddress()) // 端口合理{//让输入的textbox只读,无法改变tbHost.ReadOnly = true; tbSPort.ReadOnly = true; tbEPort.ReadOnly = true; //设置进度条的范围pb.Minimum = start; pb.Maximum = end; //显示框显示tbShow.AppendText("端口扫描器 v1.0.0" + Environment.NewLine + Environment.NewLine); //调用端口扫描函数PortScan(); }else{//若端口号不合理,弹窗报错MessageBox.Show("输入错误,端口范围为[0-65536]!"); }}catch{//若输入的端口号为非整型,则弹窗报错MessageBox.Show("输入错误,端口范围为[0-65536]!"); }}/// /// 判断端口是否合理/// ///private bool decideAddress(){//判断端口号是否合理if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))return true; elsereturn false; }private void PortScan(){double x; string xian; //显示扫描状态tbShow.AppendText("开始扫描...(可能需要请您等待几分钟)" + Environment.NewLine + Environment.NewLine); //循环抛出线程扫描端口for (int i = start; i <= end; i++){x = (double)(i - start + 1) / (end - start + 1); xian = x.ToString("0%"); port = i; //调用端口i的扫描操作Scan(); //进度条值改变lb.Text = xian; lb.Refresh(); pb.Value = https://www.it610.com/article/i; }tbShow.AppendText(Environment.NewLine +"扫描结束!" + Environment.NewLine); //输入框textbox只读属性取消tbHost.ReadOnly = false; tbSPort.ReadOnly = false; tbEPort.ReadOnly = false; }/// /// 扫描某个端口/// private void Scan(){int portnow = port; //创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接TcpClient objTCP = null; try{//用于TcpClient对象扫描端口objTCP = new TcpClient(hostAddress, portnow); //扫描到则显示到显示框tbShow.AppendText("端口 " + port + " 开放!" + Environment.NewLine); }catch{//未扫描到,则会抛出错误}}}}
2. 运行结果
文章图片
【基于C#实现端口扫描器(单线程和多线程)】可发现速度十分缓慢,且不能拖拽。
三、多线程实现端口扫描 1. 编写代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Scan{public partial class Form1 : Form{//主机地址private string hostAddress; //起始端口private int start; //终止端口private int end; //端口号private int port; //定义线程对象private Thread scanThread; //定义端口状态数据(开放则为true,否则为false)private bool[] done = new bool[65526]; private bool OK; public Form1(){InitializeComponent(); //不进行跨线程检查CheckForIllegalCrossThreadCalls = false; }private void button1_Click_1(object sender, EventArgs e){try{//初始化tbShow.Clear(); lb.Text = "0%"; //获取ip地址和始末端口号hostAddress = tbHost.Text; start = Int32.Parse(tbSPort.Text); end = Int32.Parse(tbEPort.Text); if (decideAddress()) // 端口合理{//让输入的textbox只读,无法改变tbHost.ReadOnly = true; tbSPort.ReadOnly = true; tbEPort.ReadOnly = true; //创建线程,并创建ThreadStart委托对象Thread process = new Thread(new ThreadStart(PortScan)); process.Start(); //设置进度条的范围pb.Minimum = start; pb.Maximum = end; //显示框显示tbShow.AppendText("端口扫描器 v1.0.0" + Environment.NewLine + Environment.NewLine); }else{//若端口号不合理,弹窗报错MessageBox.Show("输入错误,端口范围为[0-65536]!"); }}catch{//若输入的端口号为非整型,则弹窗报错MessageBox.Show("输入错误,端口范围为[0-65536]!"); }}/// /// 判断端口是否合理/// ///private bool decideAddress(){//判断端口号是否合理if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))return true; elsereturn false; }private void PortScan(){double x; string xian; //显示扫描状态tbShow.AppendText("开始扫描...(可能需要请您等待几分钟)" + Environment.NewLine + Environment.NewLine); //循环抛出线程扫描端口for (int i = start; i <= end; i++){x = (double)(i - start + 1) / (end - start + 1); xian = x.ToString("0%"); port = i; //使用该端口的扫描线程scanThread = new Thread(new ThreadStart(Scan)); scanThread.Start(); //使线程睡眠System.Threading.Thread.Sleep(100); //进度条值改变lb.Text = xian; pb.Value = https://www.it610.com/article/i; }while (!OK){OK = true; for (int i = start; i <= end; i++){if (!done[i]){OK = false; break; }}System.Threading.Thread.Sleep(1000); }tbShow.AppendText(Environment.NewLine +"扫描结束!" + Environment.NewLine); //输入框textbox只读属性取消tbHost.ReadOnly = false; tbSPort.ReadOnly = false; tbEPort.ReadOnly = false; }/// /// 扫描某个端口/// private void Scan(){int portnow = port; //创建线程变量Thread Threadnow = scanThread; //扫描端口,成功则写入信息done[portnow] = true; //创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接TcpClient objTCP = null; try{//用于TcpClient对象扫描端口objTCP = new TcpClient(hostAddress, portnow); //扫描到则显示到显示框tbShow.AppendText("端口 " + port + " 开放!" + Environment.NewLine); }catch{//未扫描到,则会抛出错误}}}}
2. 运行结果
可发现速度明显变快,且能拖拽窗口。
四、总结 多线程可以提高CPU的利用率。
以上就是基于C#实现端口扫描器(单线程和多线程)的详细内容,更多关于C# 端口扫描器的资料请关注脚本之家其它相关文章!
推荐阅读
- 基于微信小程序带后端ssm接口小区物业管理平台设计
- 关于QueryWrapper|关于QueryWrapper,实现MybatisPlus多表关联查询方式
- MybatisPlus使用queryWrapper如何实现复杂查询
- python学习之|python学习之 实现QQ自动发送消息
- 基于|基于 antd 风格的 element-table + pagination 的二次封装
- 孩子不是实现父母欲望的工具——林哈夫
- opencv|opencv C++模板匹配的简单实现
- Node.js中readline模块实现终端输入
- java中如何实现重建二叉树
- 基于爱,才会有“愿望”当“要求”。2017.8.12