C#端口扫描器
单线程
但VS下设计以下界面:
其中有一个listbox,5个label,一个progressBar,一个button,三个textBox。
然后在Form1.cs下书写以下代码:
using System;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
namespace scanAPP
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
//自定义变量
// private int port;
private string Addr;
private bool[] done = new bool[65536];
private int start;
private int end;
// private Thread scanThread;
private bool OK;
private void txtStart_TextChanged(object sender, System.EventArgs e)
{
//获取输入的起始端口值
textBox1.Text = textBox2.Text;
}
private void txtEnd_TextChanged(object sender, System.EventArgs e)
{
//获取输入的结束端口值
textBox2.Text = textBox3.Text;
}
private void button1_Click(object sender, EventArgs e)
{
//创建线程,并创建ThreadStart委托对象
Thread process = new Thread(PortScan);
process.Start();
//显示端口扫描的范围
progressBar1.Minimum = Int32.Parse(textBox2.Text);
progressBar1.Maximum = Int32.Parse(textBox3.Text);
//显示框初始化
listBox1.Items.Clear();
listBox1.Items.Add("端口扫描器 v1.0.");
listBox1.Items.Add("");
}
private void PortScan()
{
start = Int32.Parse(textBox2.Text);
end = Int32.Parse(textBox3.Text);
//检查输入范围合法性
if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
{
listBox1.Items.Add("开始扫描... (可能需要请您等待几分钟)");
Addr = textBox1.Text;
for (int i = start; i <= end; i++)
{
progressBar1.Value = i;
label6.Text = i.ToString();
try
{
TcpClient tcp = new TcpClient(Addr, i);
listBox1.Items.Add("端口 " + i.ToString() + " 开放!");
}
catch
{
}
}
while (!OK)
{
OK = true;
for (int i = start; i <= end; i++)
{
if (!done[i])
{
OK = false;
break;
}
}
Thread.Sleep(1000);
}
listBox1.Items.Add("扫描结束!");
}
else
{
MessageBox.Show("输入错误,端口范围为[0-65536]");
}
}
}
}
运行如下:
多线程
界面设置同上图(单线程)。
源代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Net.Sockets;
namespace scanAPP2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//禁止捕获错误线程
CheckForIllegalCrossThreadCalls = false;
}
//自定义变量
private int port;
private string Addr;
private bool[] done = new bool[65536];
private int start;
private int end;
private Thread scanThread;
private bool OK;
private void txtStart_TextChanged(object sender, System.EventArgs e)
{
//获取输入的起始端口值
textBox1.Text = textBox2.Text;
}
private void txtEnd_TextChanged(object sender, System.EventArgs e)
{
//获取输入的结束端口值
textBox2.Text = textBox3.Text;
}
private void button1_Click(object sender, EventArgs e)
{
//创建线程,并创建ThreadStart委托对象
Thread process = new Thread(new ThreadStart(PortScan));
process.Start();
//显示端口扫描的范围
progressBar1.Minimum = Int32.Parse(textBox2.Text);
progressBar1.Maximum = Int32.Parse(textBox3.Text);
//显示框初始化
listBox1.Items.Clear();
listBox1.Items.Add("端口扫描器 v1.0.");
listBox1.Items.Add("");
}
private void PortScan()
{
start = Int32.Parse(textBox2.Text);
end = Int32.Parse(textBox3.Text);
//检查输入范围合法性
if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
{
listBox1.Items.Add("开始扫描... (可能需要请您等待几分钟)");
Addr = textBox1.Text;
for (int i = start; i <= end; i++)
{
port = i;
//使用该端口的扫描线程
scanThread = new Thread(new ThreadStart(Scan));
scanThread.Start();
//使线程睡眠
System.Threading.Thread.Sleep(100);
progressBar1.Value = i;
label5.Text = i.ToString();
}
//未完成时情况
while (!OK)
{
OK = true;
for (int i = start; i <= end; i++)
{
if (!done[i])
{
OK = false;
break;
}
}
System.Threading.Thread.Sleep(1000);
}
listBox1.Items.Add("扫描结束!");
}
else
{
MessageBox.Show("输入错误,端口范围为[0-65536]");
}
}
private void Scan()
{
int portnow = port;
//创建线程变量
Thread Threadnow = scanThread;
done[portnow] = true;
//创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接
TcpClient objTCP = null;
//扫描端口,成功则写入信息
try
{
//用TcpClient对象扫描端口
objTCP = new TcpClient(Addr, portnow);
listBox1.Items.Add("端口 " + portnow.ToString() + " 开放!");
}
catch
{
}
}
}
}
运行结果:
总结
与单线程相比,多线程会快很多,因为CPU多线程的算力更强大。所以我合理推断,运行速度还和CPU的核心数和频率有关系。