基于C#实现端口扫描器(单线程和多线程)
端口扫描器是渗透测试和网络安全领域中一个非常重要的工具,它用于发现网络主机上开放的TCP/UDP端口。本文将基于C#实现一个简单的端口扫描器并探讨如何使用单线程和多线程技术来提高效率。
端口扫描器实现流程
- 解析待扫描主机的IP地址和端口范围
- 循环遍历端口范围,尝试向目标主机的每个端口发送TCP或UDP连接请求
- 根据返回结果,确定目标主机上的端口是否开放
单线程实现端口扫描器
下面是基于单线程的端口扫描器实现代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace SimplePortScanner
{
class Program
{
static void Main(string[] args)
{
string host = "127.0.0.1"; // 待扫描主机
int startPort = 1000; // 起始端口
int endPort = 2000; // 结束端口
for (int port = startPort; port <= endPort; port++)
{
try
{
TcpClient client = new TcpClient();
client.Connect(host, port);
Console.WriteLine($"Port {port}: OPEN");
client.Close();
}
catch (SocketException)
{
Console.WriteLine($"Port {port}: CLOSED");
}
}
}
}
}
在该实现中,我们通过循环遍历给定的端口范围,使用TcpClient
发送TCP连接请求并捕获可能的异常信息来判断目标主机上的端口是否开放。
多线程实现端口扫描器
下面是基于多线程技术的端口扫描器实现代码:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace MultiThreadPortScanner
{
class Program
{
static void Main(string[] args)
{
string host = "127.0.0.1"; // 待扫描主机
int startPort = 1000; // 起始端口
int endPort = 2000; // 结束端口
int threadCount = 10; // 线程数
int perThreadPorts = (endPort - startPort + 1) / threadCount;
for (int i = 0; i < threadCount; i++)
{
int start = startPort + perThreadPorts * i;
int end = i == threadCount - 1 ? endPort : start + perThreadPorts - 1;
ThreadPool.QueueUserWorkItem(new WaitCallback(ScanPorts), new PortRange(host, start, end));
}
Console.ReadLine();
}
static void ScanPorts(object state)
{
PortRange range = (PortRange)state;
for (int port = range.StartPort; port <= range.EndPort; port++)
{
try
{
TcpClient client = new TcpClient();
client.Connect(range.Host, port);
Console.WriteLine($"Port {port}: OPEN");
client.Close();
}
catch (SocketException)
{
Console.WriteLine($"Port {port}: CLOSED");
}
}
}
}
class PortRange
{
public string Host { get; set; }
public int StartPort { get; set; }
public int EndPort { get; set; }
public PortRange(string host, int start, int end)
{
Host = host;
StartPort = start;
EndPort = end;
}
}
}
该实现中,我们使用线程池来创建多个工作线程,并将端口范围分配给不同的线程进行扫描。每个工作线程使用一个PortRange
对象来存储其分配到的端口范围。这里我们假设待扫描的端口数量可以被线程数整除,因此每个工作线程的端口范围大小相等。
示例
假设我们的目标主机为127.0.0.1,起始端口为1000,结束端口为2000。我们可以运行上述代码来进行端口扫描。
如果运行单线程端口扫描器,输出结果如下:
Port 1000: CLOSED
Port 1001: CLOSED
Port 1002: CLOSED
...(省略中间部分)...
Port 1998: CLOSED
Port 1999: CLOSED
Port 2000: CLOSED
我们可以看到,单线程扫描整个端口范围需要一定的时间,因此效率较低。
相比之下,如果运行多线程端口扫描器,输出结果如下:
Port 1000: CLOSED
Port 1001: CLOSED
Port 1002: CLOSED
Port 1003: CLOSED
Port 1004: CLOSED
Port 1005: CLOSED
Port 1006: CLOSED
Port 1007: CLOSED
Port 1008: CLOSED
Port 1009: CLOSED
Port 1010: CLOSED
Port 1011: CLOSED
Port 1012: CLOSED
Port 1013: CLOSED
Port 1014: CLOSED
Port 1015: CLOSED
Port 1016: CLOSED
Port 1017: CLOSED
Port 1018: CLOSED
...(省略中间部分)...
Port 1998: CLOSED
Port 1999: CLOSED
Port 2000: CLOSED
我们可以看到,多线程扫描效率显著提高,输出结果出现得更快。
这就是关于基于C#实现端口扫描器(单线程和多线程)的完整攻略。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于C#实现端口扫描器(单线程和多线程) - Python技术站