網站首頁 編程語言 正文
一、新建項目并設置界面
新建項目:
選擇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]!"); } } /// <summary> /// 判斷端口是否合理 /// </summary> /// <returns></returns> private bool decideAddress() { //判斷端口號是否合理 if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end)) return true; else return 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 = i; } tbShow.AppendText(Environment.NewLine + "掃描結束!" + Environment.NewLine); //輸入框textbox只讀屬性取消 tbHost.ReadOnly = false; tbSPort.ReadOnly = false; tbEPort.ReadOnly = false; } /// <summary> /// 掃描某個端口 /// </summary> 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. 運行結果
可發現速度十分緩慢,且不能拖拽。
三、多線程實現端口掃描
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]!"); } } /// <summary> /// 判斷端口是否合理 /// </summary> /// <returns></returns> private bool decideAddress() { //判斷端口號是否合理 if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end)) return true; else return 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 = 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; } /// <summary> /// 掃描某個端口 /// </summary> 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的利用率。
原文鏈接:https://blog.csdn.net/weixin_46628481/article/details/121440214
相關推薦
- 2022-04-27 Python學習筆記之字典,元組,布爾類型和讀寫文件_python
- 2022-03-06 SQLServer批量插入數據的三種方式及性能對比_C#教程
- 2022-12-23 C++成員函數如何當作回調函數同時傳遞this指針_C 語言
- 2022-07-06 Python中的字符串相似度_python
- 2022-04-21 新一代Python包管理工具_python
- 2023-10-15 el-input有時候添加不了有時候刪不了
- 2022-07-21 基于Spring Boot項目構建流水線
- 2022-05-17 Git分支管理策略_其它綜合
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支