При сканировании хостов нужно собрать информацию о них. Все работает, но слишком медленно - C#

Узнай цену своей работы

Формулировка задачи:

Разработал систему мониторинга. При сканировании хостов нужно собрать информацию о них. Все работает, но слишком медленно. Компьютеров несколько тысяч, а один выключенный компьютер сканируется полторы минуты. Можно ли как-то уменьшить время сканирования одного порта, которое равно ~21сек. Вещи типа SendTimeout и ReceiveTimeout не помогают. Пробовал сканировать порты с помощью асинхронных сокетов с таймаутом 3 секунды, работает хорошо, однако операционая система по истечени этого времени все равно продолжает ждать ответ. В итоге сканирутся в 50 потоков, а висит их 50 и постоянно увеличивается. Код обычного сканера:
Листинг программы
  1. struct PortScanStructure
  2. {
  3. public bool Active;
  4. public bool PortOpen;
  5. }
  6. class PortScannerOld
  7. {
  8. public static void Scan(string p_IPAddress, int p_Port, ref PortScanStructure p_PSS)
  9. {
  10. p_PSS.Active = false;
  11. p_PSS.PortOpen = false;
  12. Socket sock;
  13. sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  14. sock.ReceiveTimeout = 500;
  15. sock.SendTimeout = 100;
  16. try
  17. {
  18. sock.Connect(p_IPAddress, p_Port);
  19. }
  20. catch (SocketException se)
  21. {
  22. if (se.ErrorCode == 10061 || se.ErrorCode == 10054)
  23. p_PSS.Active = true;
  24. }
  25. finally
  26. {
  27. if (sock.Connected)
  28. {
  29. p_PSS.Active = true;
  30. p_PSS.PortOpen = true;
  31. sock.Disconnect(false);
  32. }
  33. sock.Close();
  34. }
  35. }
  36. }
Код с асинхронными сокетами
Листинг программы
  1. struct PortScanResult
  2. {
  3. public bool PortActive;
  4. public bool HostActive;
  5. public PortScanResult(bool PortState, bool HostState)
  6. {
  7. PortActive = PortState;
  8. HostActive = HostState;
  9. }
  10. }
  11. class PortScanner
  12. {
  13. private ManualResetEvent TimeoutObject = new ManualResetEvent(false);
  14. private PortScanResult Result = new PortScanResult(false, false);
  15. public PortScanner() { }
  16. ~PortScanner()
  17. {
  18. TimeoutObject.Close();
  19. }
  20. public PortScanResult Scan(string host, int port, int timeout)
  21. {
  22. TimeoutObject.Reset();
  23. Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  24. sock.BeginConnect(host, port, ConnectCallback, sock);
  25. TimeoutObject.WaitOne(timeout, false);
  26. return Result;
  27. }
  28. public void ConnectCallback(IAsyncResult AsyncResult)
  29. {
  30. Socket sock = (Socket)AsyncResult.AsyncState;
  31. try
  32. {
  33. sock.EndConnect(AsyncResult);
  34. if (sock.Connected)
  35. {
  36. sock.Shutdown(SocketShutdown.Both);
  37. sock.Disconnect(false);
  38. Result.PortActive = true;
  39. Result.HostActive = true;
  40. }
  41. }
  42. catch (SocketException se)
  43. {
  44. if (se.ErrorCode == 10054 || se.ErrorCode == 10061)
  45. {
  46. Result.PortActive = false;
  47. Result.HostActive = true;
  48. }
  49. }
  50. catch { }
  51. finally
  52. {
  53. sock.Close();
  54. TimeoutObject.Set();
  55. }
  56. }
  57. }

Решение задачи: «При сканировании хостов нужно собрать информацию о них. Все работает, но слишком медленно»

textual
Листинг программы
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Net;
  6. using System.Net.Sockets;
  7. using System.Threading;
  8.  
  9. namespace portScan2
  10. {
  11.     class Program
  12.     {
  13.         static void Main(string[] args)
  14.         {
  15.             PortScanner ps = new PortScanner();
  16.             ps.Scan("192.168.0.1", 23, 1000);
  17.             ps.Scan("192.168.0.1", 80, 1000);
  18.             ps.Scan("192.168.0.1", 135, 1000);
  19.             ps.Scan("192.168.0.1", 443, 1000);
  20.             ps.Scan("192.168.0.1", 8080, 1000);
  21.             Console.WriteLine("--->");
  22.             Console.Read();
  23.         }
  24.     }
  25.  
  26.     struct PortScanResult
  27.     {
  28.         public bool PortActive;
  29.         public bool HostActive;
  30.         public PortScanResult(bool PortState, bool HostState)
  31.         {
  32.             PortActive = PortState;
  33.             HostActive = HostState;
  34.         }
  35.     }
  36.  
  37.     class PortScanner
  38.     {
  39.         private ManualResetEvent TimeoutObject = new ManualResetEvent(false);
  40.         private PortScanResult Result = new PortScanResult(false, false);
  41.  
  42.         public PortScanner() { }
  43.  
  44.         ~PortScanner()
  45.         {
  46.             TimeoutObject.Close();
  47.         }
  48.  
  49.         public PortScanResult Scan(string host, int port, int timeout)
  50.         {
  51.             TimeoutObject.Reset();
  52.             Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  53.             sock.BeginConnect(host, port, ConnectCallback, sock);
  54.             TimeoutObject.WaitOne(timeout, false);
  55.             sock.Close();
  56.             Console.WriteLine("Scan complete");
  57.             return Result;
  58.         }
  59.  
  60.         public void ConnectCallback(IAsyncResult AsyncResult)
  61.         {
  62.             Socket sock = (Socket)AsyncResult.AsyncState;
  63.             try
  64.             {
  65.                 sock.EndConnect(AsyncResult);
  66.                 if (sock.Connected)
  67.                 {
  68.                     sock.Shutdown(SocketShutdown.Both);
  69.                     sock.Disconnect(false);
  70.                     Result.PortActive = true;
  71.                     Result.HostActive = true;
  72.                 }
  73.             }
  74.             catch (SocketException se)
  75.             {
  76.                 if (se.ErrorCode == 10054 || se.ErrorCode == 10061)
  77.                 {
  78.                     Result.PortActive = false;
  79.                     Result.HostActive = true;
  80.                 }
  81.             }
  82.             catch { }
  83.             finally
  84.             {
  85.                 sock.Close();
  86.                 TimeoutObject.Set();
  87.             }
  88.         }
  89.     }
  90. }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 3.857 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы