(3)端口扫描

本文探讨了端口扫描时采用单线程和多线程两种方式的效果。单线程扫描可能导致界面卡死且速度较慢,而多线程扫描则能显著提升扫描速度,并避免界面卡死问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

端口扫描

单线程

using System;
using System.Net;
using System.Net.Sockets;
using System.Windows.Forms;
using System.Threading;
namespace MultithreadingScanningPort
{
    public partial class Form1 : Form
    {
        private bool[] ports = new bool[65536];
        public Form1()
        {
            InitializeComponent();
            panel5.Hide();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if(int.Parse(beginPortText.Text)<0 || int.Parse(beginPortText.Text) > int.Parse(endPortText.Text)  || int.Parse(endPortText.Text)>65565)
            {
                messages.Items.Add("端口错误!");
                return;
            }

            messages.Items.Clear();
            messages.Items.Add("开始扫描.......");
            ScanningPort();

        }

        public void ScanningPort() {
            int start = int.Parse(beginPortText.Text);
            int end = int.Parse(endPortText.Text);
            messages.Items.Add("起始端口"+start);
            messages.Items.Add("结束端口" + end);
            for (int i = start; i <= end; i++)
            {
                Scanning(i);
            }

            messages.Items.Add("端口扫描结束");
        }


        public void Scanning(int port) {
            this.ports[port] = true;
            try {
                TcpClient tmp = new TcpClient(ipAddressText.Text, port);
                messages.Items.Add("端口" + port + "开放");
            }

            catch(System.Exception ex)
            {

            }
        }

    }
}

多线程

using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace SingleThreadScanningPort
{
    public partial class Form1 : Form
    {
        
        private bool[] ports = new bool[65536];//所有端口号
        private static int port=0;//当前端口号
        private static int count = 0;//开放端口号数量

        public Form1()
        {
            InitializeComponent();
            //CheckForIllegalCrossThreadCalls设置为false;然后就能安全的访问窗体控件
            CheckForIllegalCrossThreadCalls = false;

            //初始化进度显示为空
            label2.Text = "";

            //停止扫描按钮为不可用
            stopScanning.Enabled = false;
        }

        private void beginScanning_Click(object sender, EventArgs e)
        {
            //检查端口号
            if (int.Parse(beginPortText.Text) < 0 || int.Parse(beginPortText.Text) > int.Parse(endPortText.Text) || int.Parse(endPortText.Text) > 65565)
            {
                messages.Items.Add("端口错误!");
                return;
            }

            //新建线程执行扫描端口函数
            Thread procss = new Thread(new ThreadStart(ScanningPort));
            procss.Start();

            //设置进度条最大值最小值分别为结束端口和起始端口
            progressBar1.Maximum = int.Parse(endPortText.Text) - int.Parse(beginPortText.Text);
            progressBar1.Minimum = 0;

            //判断是否为继续扫描
            if (port == 0)
            {
                messages.Items.Clear();
                messages.Items.Add("开始扫描.......");
            }

            else
                messages.Items.Add("继续扫描......");

            //开始扫描禁用,停止扫描启用
            beginScanning.Enabled = false;
            stopScanning.Enabled = true;
        }
        public void ScanningPort()
        {
            int start;
            int end = int.Parse(endPortText.Text);

            //判断是否为继续扫描,如果是则继续扫描,否则重新扫描
            if (port != 0)
                start = port;
            else
                start = int.Parse(beginPortText.Text);

            messages.Items.Add("起始端口" + start);
            messages.Items.Add("结束端口" + end);


            for (int i = start; i <= end; i++)
            {

                //按下停止扫描后开始扫描按钮启用,此时停止扫描
                if (beginScanning.Enabled)
                    break;
                port = i;

                //新建线程进行扫描
                Thread thread = new Thread(Scanning);
                thread.Start();

                //主线程休眠10ms
                System.Threading.Thread.Sleep(10);

                //修改进度条的值
                progressBar1.Value = i- int.Parse(beginPortText.Text);

                //显示端口号以及进度
                label2.Text = "正在扫描端口: " + i+"  进度: "+Math.Round(( (i - int.Parse(beginPortText.Text)) *100.0 / progressBar1.Maximum),2)+"%";
                progressBar1.PerformStep();
            }

            if (port != 0)
                beginScanning.Text = "继续扫描";
            else
            {
                messages.Items.Add("端口扫描结束");
                messages.Items.Add("共有 " + count + " 个端口开放");
            }

            beginScanning.Enabled = true;
            stopScanning.Enabled = false;
           

            //判断是否扫描完毕
            if (int.Parse(endPortText.Text) == port)
            {
                port = 0;
                beginScanning.Text = "开始扫描";
            }

        }


        public void Scanning()
        {
            this.ports[port] = true;
            try
            {
                TcpClient tmp = new TcpClient(ipAddressText.Text, port);
                messages.Items.Add("端口" + port + "开放");
                count++;
            }

            catch (System.Exception ex)
            {
               
            }
        }

        private void stopScanning_Click(object sender, EventArgs e)
        {
            //按下停止按钮后,开始按钮和停止按钮状态翻转
            beginScanning.Enabled = true;
            stopScanning.Enabled = false;
        }
    }
}

在这里插入图片描述

单线程操作的时候会出现界面直接卡死并且扫描速度很慢,
多线程操作扫描速度大大提升而且不会出现界面卡死

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值