软件编程
位置:首页>> 软件编程>> C#编程>> C# 基于TCP 实现扫描指定ip端口的方式示例

C# 基于TCP 实现扫描指定ip端口的方式示例

作者:醉意丶千层梦  发布时间:2021-11-28 07:55:24 

标签:C#,扫描,ip端口

一、单线程扫描

1.代码


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;
       }
   }
}

2.界面

C# 基于TCP 实现扫描指定ip端口的方式示例

3.结果

由于是单线程执行,在扫描端口的时候程序会直接卡死。所以只简单扫描几个端口

C# 基于TCP 实现扫描指定ip端口的方式示例

4.抓包

由于是通过以太网发送的,建议先注销哆点再进行抓包,减少数据。
可以发现3900端口成功实现三次握手,即该端口是开放的。而其他端口(红色)则是无法建立连接,意味着是关闭的。

C# 基于TCP 实现扫描指定ip端口的方式示例

二、多线程扫描

1.代码


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;
       }
   }
}

2.界面

C# 基于TCP 实现扫描指定ip端口的方式示例

3.结果

不会出现单线程的卡死,扫描速度也大大提升。同时可以随时开始和暂停操作。

C# 基于TCP 实现扫描指定ip端口的方式示例

4.抓包

和单线程的抓包思路以及结果都是一样的

三、总结

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

四、源码

1.github

https://github.com/TangtangSix/SingleThreadScanningPort

https://github.com/TangtangSix/MultithreadingScanningPort

2.gitee

https://gitee.com/tangtangsix/SingleThreadScanningPort
https://gitee.com/tangtangsix/MultithreadingScanningPort

来源:https://blog.csdn.net/qq_47281915/article/details/121500591

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com