当前位置 : 主页 > 网络编程 > c#编程 >

C#单线程和多线程端口扫描器详解

来源:互联网 收集:自由互联 发布时间:2023-01-31
目录 一、项目创建以及页面设计 (一)项目新建 (二)页面设计 二、单线程实现端口扫描 (一)代码实现 (二)运行结果 三、多线程实现端口扫描 (一)程序实现 (二)运行结果
目录
  • 一、项目创建以及页面设计
    • (一)项目新建
    • (二)页面设计
  • 二、单线程实现端口扫描
    • (一)代码实现
    • (二)运行结果
  • 三、多线程实现端口扫描
    • (一)程序实现
    • (二)运行结果
  • 四、总结
    • 五、参考资料

      本文为大家分享了C#单线程和多线程端口扫描器,供大家参考,具体内容如下

      一、项目创建以及页面设计

      (一)项目新建

      1.选择Windows窗体项目应用(.Net Framework)->下一步:

      2.项目命名以及合适的存储位置,选择创建

      (二)页面设计

      1.点开工具箱,需要4个Label,一个Button,一个Progress,4个TextBox

      2.横向拉伸TextBox

      (1)点击三角形

      (2)勾选Multiline后拉伸

      (3)设置控件的名称和唯一标志

      设置唯一标志

      修改显示名称

      (4)页面设计如下

      (5)设置消息显示界面的 TextBox 不可编辑:找到 Enabled 属性,参数设为 False 。

      二、单线程实现端口扫描

      (一)代码实现

      1.双击按钮btnShow

      2.编写代码

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Net.Sockets;
      using System.Text;
      using System.Threading;
      using System.Threading.Tasks;
      using System.Windows.Forms;
      
      namespace cqjtuWindowsFormsApp
      {
          public partial class Form1 : Form
          {
      
                  private string hostAddress;
                  //起始端口
                  private int start;
                  //终止端口
                  private int end;
                  //端口号
                  private int port;
                  //定义线程对象
                  private Thread scanThread;
                  public Form1()
                  {
                      InitializeComponent();
                  }
      
                  private void label1_Click(object sender, EventArgs e)
                  {
      
                  }
      
                  private void label2_Click(object sender, EventArgs e)
                  {
      
                  }
      
                  private void label4_Click(object sender, EventArgs e)
                  {
      
                  }
      
                  private void button1_Click(object sender, EventArgs e)
                  {
                      try
                      {
                          //初始化
                          tbShow.Clear();
                          lb.Text = "0%";
      
                          //获取ip地址和始末端口号
                          hostAddress = tbHost.Text;
                          start = Int32.Parse(tbSPort.Text);
                          end = Int32.Parse(tbEPort.Text);
      
                          if (decideAddress()) // 端口合理
                          {
                              //让输入的textbox只读,无法改变
                              tbHost.ReadOnly = true;
                              tbSPort.ReadOnly = true;
                              tbEPort.ReadOnly = true;
                              //设置进度条的范围
                              pb.Minimum = start;
                              pb.Maximum = end;
      
                              //显示框显示
                              tbShow.AppendText("端口扫描器 v1.0.0" + Environment.NewLine + Environment.NewLine);
                              //调用端口扫描函数
                              PortScan();
                          }
                          else
                          {
                              //若端口号不合理,弹窗报错
                              MessageBox.Show("输入错误,端口范围为[0-65536]!");
                          }
                      }
                      catch
                      {
                          //若输入的端口号为非整型,则弹窗报错
                          MessageBox.Show("输入错误,端口范围为[0-65536]!");
                      }
                  }
                  /// <summary>
                  /// 判断端口是否合理
                  /// </summary>
                  /// <returns></returns>
                  private bool decideAddress()
                  {
                      //判断端口号是否合理
                      if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
                          return true;
                      else
                          return false;
                  }
                  private void PortScan()
                  {
                      double x;
                      string xian;
                      //显示扫描状态
                      tbShow.AppendText("开始扫描...(可能需要请您等待几分钟)" + Environment.NewLine + Environment.NewLine);
                      //循环抛出线程扫描端口
                      for (int i = start; i <= end; i++)
                      {
                          x = (double)(i - start + 1) / (end - start + 1);
                          xian = x.ToString("0%");
                          port = i;
                          //调用端口i的扫描操作
                          Scan();
                          //进度条值改变
                          lb.Text = xian;
                          lb.Refresh();
                          pb.Value = i;
                      }
                      tbShow.AppendText(Environment.NewLine + "扫描结束!" + Environment.NewLine);
                      //输入框textbox只读属性取消
                      tbHost.ReadOnly = false;
                      tbSPort.ReadOnly = false;
                      tbEPort.ReadOnly = false;
                  }
      
                  /// <summary>
                  /// 扫描某个端口
                  /// </summary>
                  private void Scan()
                  {
                      int portnow = port;
                      //创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接
                      TcpClient objTCP = null;
                      try
                      {
                          //用于TcpClient对象扫描端口
                          objTCP = new TcpClient(hostAddress, portnow);
                          //扫描到则显示到显示框
                          tbShow.AppendText("端口 " + port + " 开放!" + Environment.NewLine);
                      }
                      catch
                      {
                          //未扫描到,则会抛出错误
                      }
                  }
      
              }
      }

      (二)运行结果

      1.启动项目

      2.输入相关信息

      3.扫描结果

      三、多线程实现端口扫描

      (一)程序实现

      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Net.Sockets;
      using System.Text;
      using System.Threading;
      using System.Threading.Tasks;
      using System.Windows.Forms;
      
      namespace cqjtuWindowsFormsApp
      {
          public partial class Form1 : Form
          {
      
                  private string hostAddress;
                  //起始端口
                  private int start;
                  //终止端口
                  private int end;
                  //端口号
                  private int port;
                  //定义线程对象
                  private Thread scanThread;
                 //定义端口状态数据(开放则为true,否则为false)
                 private bool[] done = new bool[65526];
                 private bool OK;
              public Form1()
                  {
                      InitializeComponent();
                  //不进行跨线程检查
                  CheckForIllegalCrossThreadCalls = false;
              }
      
                  private void label1_Click(object sender, EventArgs e)
                  {
      
                  }
      
                  private void label2_Click(object sender, EventArgs e)
                  {
      
                  }
      
                  private void label4_Click(object sender, EventArgs e)
                  {
      
                  }
      
                  private void button1_Click(object sender, EventArgs e)
                  {
                  try
                  {
                      //初始化
                      tbShow.Clear();
                      lb.Text = "0%";
      
                      //获取ip地址和始末端口号
                      hostAddress = tbHost.Text;
                      start = Int32.Parse(tbSPort.Text);
                      end = Int32.Parse(tbEPort.Text);
      
                      if (decideAddress()) // 端口合理
                      {
                          //让输入的textbox只读,无法改变
                          tbHost.ReadOnly = true;
                          tbSPort.ReadOnly = true;
                          tbEPort.ReadOnly = true;
                          //创建线程,并创建ThreadStart委托对象
                          Thread process = new Thread(new ThreadStart(PortScan));
                          process.Start();
                          //设置进度条的范围
                          pb.Minimum = start;
                          pb.Maximum = end;
      
                          //显示框显示
                          tbShow.AppendText("端口扫描器 v1.0.0" + Environment.NewLine + Environment.NewLine);
                      }
                      else
                      {
                          //若端口号不合理,弹窗报错
                          MessageBox.Show("输入错误,端口范围为[0-65536]!");
                      }
      
                  }
                  catch
                  {
                      //若输入的端口号为非整型,则弹窗报错
                      MessageBox.Show("输入错误,端口范围为[0-65536]!");
                  }
      
                  }
                  /// <summary>
                  /// 判断端口是否合理
                  /// </summary>
                  /// <returns></returns>
                  private bool decideAddress()
                  {
                      //判断端口号是否合理
                      if ((start >= 0 && start <= 65536) && (end >= 0 && end <= 65536) && (start <= end))
                          return true;
                      else
                          return false;
                  }
                  private void PortScan()
                  {
                  double x;
                  string xian;
                  //显示扫描状态
                  tbShow.AppendText("开始扫描...(可能需要请您等待几分钟)" + Environment.NewLine + Environment.NewLine);
                  //循环抛出线程扫描端口
                  for (int i = start; i <= end; i++)
                  {
                      x = (double)(i - start + 1) / (end - start + 1);
                      xian = x.ToString("0%");
                      port = i;
                      //使用该端口的扫描线程
                      scanThread = new Thread(new ThreadStart(Scan));
                      scanThread.Start();
                      //使线程睡眠
                      System.Threading.Thread.Sleep(100);
                      //进度条值改变
                      lb.Text = xian;
                      pb.Value = i;
                  }
                  while (!OK)
                  {
                      OK = true;
                      for (int i = start; i <= end; i++)
                      {
                          if (!done[i])
                          {
                              OK = false;
                              break;
                          }
                      }
                      System.Threading.Thread.Sleep(1000);
                  }
                  tbShow.AppendText(Environment.NewLine + "扫描结束!" + Environment.NewLine);
                  //输入框textbox只读属性取消
                  tbHost.ReadOnly = false;
                  tbSPort.ReadOnly = false;
                  tbEPort.ReadOnly = false;
                  }
      
                  /// <summary>
                  /// 扫描某个端口
                  /// </summary>
                  private void Scan()
                  {
                      int portnow = port;
                  //创建线程变量
                  Thread Threadnow = scanThread;
                  //扫描端口,成功则写入信息
                  done[portnow] = true;
                  //创建TcpClient对象,TcpClient用于为TCP网络服务提供客户端连接
                  TcpClient objTCP = null;
                  try
                  {
                      //用于TcpClient对象扫描端口
                      objTCP = new TcpClient(hostAddress, portnow);
                      //扫描到则显示到显示框
                      tbShow.AppendText("端口 " + port + " 开放!" + Environment.NewLine);
                  }
                  catch
                  {
                      //未扫描到,则会抛出错误
                  }
                  }
      
              }
      }

      (二)运行结果

      1.启动项目

      2.输入相关信息

      3.扫描结果

      可以发现多线程扫描只需要十几秒,而单线程需要几分钟,明显多线程比单线程更快些

      四、总结

      可以发现多线程能够有更好的CPU使用率,可以使程序设计更简单,明显可以看见多线程拥有更快的程序响应速度。

      五、参考资料

      C#实现端口扫描器

      以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自由互联。

      上一篇:C#实现自定义光标并动态切换
      下一篇:没有了
      网友评论