public static void NonBlockingScan(string sIpAddress, int iStartPort, int iEndPort) { LinkedList <ConnData> hConnections = new LinkedList <ConnData>(); for (int i = iStartPort; i < iEndPort; i++) { ConnData hData = new ConnData(); hData.S = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); hData.S.Blocking = false; hData.Port = i; hData.Node = hConnections.AddFirst(hData); } List <ConnData> hToRemove = new List <ConnData>(); //dobbiamo interrogare i socket fino a quando non hanno finito tutti di lavorare while (hConnections.Count > 0) { foreach (var node in hConnections) { try { node.S.Connect(sIpAddress, node.Port); Console.WriteLine(sIpAddress + ":" + node.Port + " is Open"); hToRemove.Add(node); } catch (SocketException hEx) { if (hEx.SocketErrorCode == SocketError.WouldBlock) { //In questo caso devo aspettare e riprovare dopo.. quindi non faccio niente } else { Console.WriteLine(sIpAddress + ":" + node.Port); hToRemove.Add(node); } } } hToRemove.ForEach(x => hConnections.Remove(x)); } }
//Eseguiamo tanti tentativi di connessioni quanto l'OS riesce a gestire public static void AsyncScan(string sIpAddress, int iStartPort, int iEndPort) { int iAmmount = iEndPort - iStartPort; using (CountdownEvent hCountDown = new CountdownEvent(iAmmount)) { for (int i = iStartPort; i < iEndPort; i++) { Socket hSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ConnData vData = new ConnData(); vData.S = hSocket; vData.Port = i; //Il threading in questo modello viene gestito dietro le quinte dall'OS che lo fa sicuramente meglio di noi hSocket.BeginConnect(sIpAddress, i, (hRes) => { ConnData hConn = hRes.AsyncState as ConnData; try { hConn.S.EndConnect(hRes); //dammi il risultato dell'operazione Console.WriteLine(sIpAddress + ":" + hConn.Port + " is Open"); } catch (Exception) { Console.WriteLine(sIpAddress + ":" + hConn.Port); } finally { hConn.S.Close(); hCountDown.Signal(); } }, vData); } hCountDown.Wait(); } }