端口扫描器
单一进程
在VS2019中
设计如图的界面
在Form1.cs中添加如下代码
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 端口扫描器
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
System.Windows.Forms.Control.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;
lblNow.Text = i.ToString();
try
{
TcpClient tcp = new TcpClient(Addr, i);
listBox1.Items.Add("端口 " + i.ToString() + " 开放!");
}
catch
{
}
}
//for (int i = start; i <= end; i++)
//{
// port = i;
// //使用该端口的扫描线程
// Thread scanThread = new Thread(new ThreadStart(Scan));
// scanThread.Start();
// //使线程睡眠
// System.Threading.Thread.Sleep(100);
// progressBar1.Value = i;
// lblNow.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]");
}
}
运行结果如下
多进程
设置如上的界面
在Form.cs中写如下代码
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 端口扫描器
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//禁止捕获错误线程
System.Windows.Forms.Control.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;
lblNow.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
{
}
}
}
}
运行结果
总结
可以明显的看到,多线程的速度比单线程快了不止一点点,深入理解了多线程和单线程的区别。