基于C#實現(xiàn)端口掃描器(單線程和多線程)
更新時間:2022年07月27日 16:05:48 作者:Baker_Streets
本文主要介紹了基于C#分別通過單線程和多線程實現(xiàn)端口掃描,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
一、新建項目并設(shè)置界面
新建項目:
選擇Windows窗體項目應(yīng)用(.Net Framework):

設(shè)置項目名和路徑:

新建項目如下:

設(shè)置界面:

將tbShow設(shè)置為只讀:

二、單線程實現(xiàn)端口掃描
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;
//設(shè)置進度條的范圍
pb.Minimum = start;
pb.Maximum = end;
//顯示框顯示
tbShow.AppendText("端口掃描器 v1.0.0" + Environment.NewLine + Environment.NewLine);
//調(diào)用端口掃描函數(shù)
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;
//顯示掃描狀態(tài)
tbShow.AppendText("開始掃描...(可能需要請您等待幾分鐘)" + Environment.NewLine + Environment.NewLine);
//循環(huán)拋出線程掃描端口
for (int i = start; i <= end; i++)
{
x = (double)(i - start + 1) / (end - start + 1);
xian = x.ToString("0%");
port = i;
//調(diào)用端口i的掃描操作
Scan();
//進度條值改變
lb.Text = xian;
lb.Refresh();
pb.Value = i;
}
tbShow.AppendText(Environment.NewLine + "掃描結(jié)束!" + Environment.NewLine);
//輸入框textbox只讀屬性取消
tbHost.ReadOnly = false;
tbSPort.ReadOnly = false;
tbEPort.ReadOnly = false;
}
/// <summary>
/// 掃描某個端口
/// </summary>
private void Scan()
{
int portnow = port;
//創(chuàng)建TcpClient對象,TcpClient用于為TCP網(wǎng)絡(luò)服務(wù)提供客戶端連接
TcpClient objTCP = null;
try
{
//用于TcpClient對象掃描端口
objTCP = new TcpClient(hostAddress, portnow);
//掃描到則顯示到顯示框
tbShow.AppendText("端口 " + port + " 開放!" + Environment.NewLine);
}
catch
{
//未掃描到,則會拋出錯誤
}
}
}
}
2. 運行結(jié)果

可發(fā)現(xiàn)速度十分緩慢,且不能拖拽。
三、多線程實現(xiàn)端口掃描
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;
//定義端口狀態(tài)數(shù)據(jù)(開放則為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;
//創(chuàng)建線程,并創(chuàng)建ThreadStart委托對象
Thread process = new Thread(new ThreadStart(PortScan));
process.Start();
//設(shè)置進度條的范圍
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;
//顯示掃描狀態(tài)
tbShow.AppendText("開始掃描...(可能需要請您等待幾分鐘)" + Environment.NewLine + Environment.NewLine);
//循環(huán)拋出線程掃描端口
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 + "掃描結(jié)束!" + Environment.NewLine);
//輸入框textbox只讀屬性取消
tbHost.ReadOnly = false;
tbSPort.ReadOnly = false;
tbEPort.ReadOnly = false;
}
/// <summary>
/// 掃描某個端口
/// </summary>
private void Scan()
{
int portnow = port;
//創(chuàng)建線程變量
Thread Threadnow = scanThread;
//掃描端口,成功則寫入信息
done[portnow] = true;
//創(chuàng)建TcpClient對象,TcpClient用于為TCP網(wǎng)絡(luò)服務(wù)提供客戶端連接
TcpClient objTCP = null;
try
{
//用于TcpClient對象掃描端口
objTCP = new TcpClient(hostAddress, portnow);
//掃描到則顯示到顯示框
tbShow.AppendText("端口 " + port + " 開放!" + Environment.NewLine);
}
catch
{
//未掃描到,則會拋出錯誤
}
}
}
}
2. 運行結(jié)果

可發(fā)現(xiàn)速度明顯變快,且能拖拽窗口。
四、總結(jié)
多線程可以提高CPU的利用率。
參考
以上就是基于C#實現(xiàn)端口掃描器(單線程和多線程)的詳細內(nèi)容,更多關(guān)于C# 端口掃描器的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#使用FtpWebRequest與FtpWebResponse完成FTP操作
這篇文章介紹了C#使用FtpWebRequest與FtpWebResponse完成FTP操作的方法,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05
C# 向Word中設(shè)置/更改文本方向的方法(兩種)
在一般情況下word中輸入的文字都是橫向的,今天小編給大家?guī)韮煞N方法來設(shè)置更改文本方向的方法,非常不錯,對c# word 更改文本方向的知識感興趣的朋友一起看看吧2016-08-08

