单线程
工具:vs2017
新建C#Windows窗体应用,打开界面设计,布局如下:
其余函数及控件功能实现在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]");
}
}
效果:
多线程
工具:vs2017
新建C#Windows窗体应用,打开界面设计,布局如下:
其余函数及控件功能实现在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(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
{
}
}
}
}
程序运行效果
总结
多线程创建是通过循环创建线程来实现的
单线程扫描器就是龟速,多线程快了起码10倍