C# 端口扫描

暗月博客 2019年11月21日21:31:54评论373 views字数 2939阅读9分47秒阅读模式
摘要

1.端口扫描原理 主要是利用套接字,来和远程主机的逐个端口进行连接,如果连接上说明该端口是开放的,否则是关闭的。当然现在各种安全技术发展迅速,使得这种方法扫描的端口可能不太准确,但是总得从最基本的学起吧~~

1.端口扫描原理

主要是利用套接字,来和远程主机的逐个端口进行连接,如果连接上说明该端口是开放的,否则是关闭的。当然现在各种安全技术发展迅速,使得这种方法扫描的端口可能不太准确,但是总得从最基本的学起吧~~

实现起来也不难,关键是看执行效率如何,如果使用传统的逐个端口扫描,效率很低,即使是扫描本机,平均每个端口也需要1秒左右。提高效率的方法有很多如多线程、异步扫描。我采用的是异步扫描方式,其实这种方式也是一种多线程的方式,只是线程是交由系统创建的。

 

2.程序效果截图

C# 端口扫描

 C# 端口扫描

3.源代码

说明:下面代码使用的是原始的Socket,也可以使用C#提供的高级类TcpClient,这样可能做起来会方便点。

using System; using System.Net; using System.Net.Sockets; using System.Collections;  namespace PortScan {     class Program     {         static void Main(string[] args)         {             IPAddress ip;             int startPort, endPort;             if (GetPortRange(args, out ip, out startPort, out endPort) == true)  //提取命令行参数             {                 Scan(ip, startPort, endPort);   //端口扫描                 Console.ReadKey();             }         }          #region 从命令行参数 中提取端口 + static bool GetPortRange(string[] args, out int startPort, out int endPort)                 /// <summary>         /// 从命令行参数 中提取端口         /// </summary>         /// <param name="args">命令行参数</param>         /// <param name="ip">输出 IP地址</param>         /// <param name="startPort">输出 起始端口号</param>         /// <param name="endPort">输出 终止端口号</param>         /// <returns>提取成功返回true,否则返回false</returns>         private static bool GetPortRange(string[] args,out IPAddress ip, out int startPort, out int endPort)         {             ip = null;             startPort = endPort = 0;             //帮助 命令             if (args.Length != 0 && (args[0] == "/?" || args[0] == "/help"))             {                 Console.WriteLine("Scan port from startPort to endPort of the host specified by the IPAddress.");                 Console.WriteLine("Command Format:");                 Console.WriteLine("PortScan IPAddress startPort endPort");                 Console.WriteLine("For example:");                 Console.WriteLine("PortScan 127.0.0.1 1 1024");                 return false;             }             if (args.Length == 3)             {                 //解析端口号成功                 if (IPAddress.TryParse(args[0],out ip) && int.TryParse(args[1], out startPort) && int.TryParse(args[2], out endPort))                 {                     return true;                 }                 else                 {                     Console.WriteLine("参数格式不正确!");                     return false;                 }             }             else             {                 Console.WriteLine("参数数目不正确!");                 return false;             }         }         #endregion          /// <summary>         /// 端口 扫描         /// </summary>         /// <param name="ip">扫描的 IP地址</param>         /// <param name="startPort">起始端口号</param>         /// <param name="endPort">终止端口号</param>         static void Scan(IPAddress ip, int startPort, int endPort)         {             Random rand = new Random((int)DateTime.Now.Ticks);             Console.WriteLine("Begin Scan...");             for (int port = startPort; port < endPort; port++)             {                 Socket scanSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);                 //寻找一个未使用的端口进行绑定                 do                 {                     try                     {                         scanSocket.Bind(new IPEndPoint(IPAddress.Any, rand.Next(65535)));                         break;                     }                     catch                     {                          //绑定失败                     }                 } while (true);                                 try                 {                     scanSocket.BeginConnect(new IPEndPoint(ip, port), ScanCallBack, new ArrayList() { scanSocket, port});                 }                 catch                 {                    // Console.WriteLine("port {0,5}/tClosed./n{1}", port, ex.Message);                     continue;                 }                            }              Console.WriteLine("Port Scan Completed!");         }          /// <summary>         /// BeginConnect的回调函数         /// </summary>         /// <param name="result">异步Connect的结果</param>         static void ScanCallBack(IAsyncResult result)         {             //解析 回调函数输入 参数             ArrayList arrList = (ArrayList)result.AsyncState;             Socket scanSocket = (Socket)arrList[0];             int port = (int)arrList[1];             //判断端口是否开放             if (result.IsCompleted && scanSocket.Connected)             {                 Console.WriteLine("port {0,5}/tOpen.", port);             }             else             {                 //Console.WriteLine("port {0,5}/tClosed.", port);              }             //关闭套接字             scanSocket.Close();         }     } } 

4.进化成WinForm

本来是打算直接拿WinForm来说的,但是WinForm里面有许多无关代码,所以又写了个Console的示例(也就是上面的程序),下面是用WinForm写的,原理与上面一样,只是界面友好一点而已。

C# 端口扫描

http://blog.csdn.net/xiaohui_hubei/article/details/7515103

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
暗月博客
  • 本文由 发表于 2019年11月21日21:31:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   C# 端口扫描https://cn-sec.com/archives/72064.html

发表评论

匿名网友 填写信息