Я пытаюсь написать простой сканер портов подключения.Я тестирую его на первых портах 10K на scanme.nmap.org.Он должен видеть порты 22, 80 и 9929. Если я сканирую 1 - 10000, он находит 22 и 80, но не видит 9929. Если я сначала сканирую 9900 до 10000, то 1-10000 (как в примере ниже), он видит 9929, но часто не видит порт 80 или 22.
Я знаю, что мог бы попробовать использовать WinPcap через оболочку .NET и перейти на более низкий уровень, но есть ли в любом случае простой сканер портов TCP, работающий надежно безWinPcap?
Примечание. В настоящее время я выполняю сканирование партиями по 100, потому что получаю еще худшие результаты, если выполняю их большими кусками.
using System;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace ps
{
internal class Program
{
private const int batchSize = 100;
public static void Main(string[] args)
{
int minPort = Convert.ToInt32(args[0]);
int maxPort = Convert.ToInt32(args[1]);
int loops;
if (maxPort < batchSize)
{
loops = 1;
}
else
{
loops = maxPort/batchSize;
}
// If I look for 9929 in the inital 100 - I can find it
Parallel.For(9900, 10000, port =>
{
string host = "scanme.nmap.org";
bool res = TryConnect(host, port, 5000);
if (res)
{
Console.WriteLine("\nConnected: " + port + "\n");
}
});
// now loop through all ports in batches
// should see 22, 80 & 9929 but normally doesn't
for (int i = 0; i < loops; i++)
{
minPort = 1 + (i*batchSize);
if (loops != 1)
{
maxPort = batchSize + (i*batchSize);
}
Console.WriteLine("minPort:" + minPort + " maxPort:" + maxPort);
Parallel.For(minPort, maxPort, port =>
{
string host = "scanme.nmap.org";
bool res = TryConnect(host, port, 5000);
if (res)
{
Console.WriteLine("\nConnected: " + port + "\n");
}
});
}
// Can see port 22 and 80 still?
Parallel.For(1, 100, port =>
{
string host = "scanme.nmap.org";
bool res = TryConnect(host, port, 5000);
if (res)
{
Console.WriteLine("\nConnected: " + port + "\n");
}
});
}
private static bool TryConnect(string strIpAddress, int intPort, int nTimeoutMsec)
{
Socket socket = null;
bool retval = false;
try
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IAsyncResult result = socket.BeginConnect(strIpAddress, intPort, null, null);
bool success = result.AsyncWaitHandle.WaitOne(nTimeoutMsec, true);
retval = socket.Connected;
}
catch
{
Console.WriteLine("error: " + intPort);
retval = false;
}
finally
{
if (null != socket)
socket.Close();
}
return retval;
}
}
}