find all ip address in a network

Solution 1:

This code scans my network 255 D-class segments in about 1 sec. I wrote it in VB.net and translated it to C# (apologies if there are any errors). Paste it into a Console project and run. Modify as needed.

Note: The code is not production ready and need improvements on especially the instance counting (try implement a TaskFactory with a BlockingCollection instead).

Modify ttl (time-to-live) and timeout if unstable result-wise.

Running the code will give a result like this:

Pinging 255 destinations of D-class in 192.168.1.*
Active IP: 192.168.1.100
Active IP: 192.168.1.1
Finished in 00:00:00.7226731. Found 2 active IP-addresses.

C# code:

using System.Net.NetworkInformation;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;
using System;

static class Module1
{
    private static List<Ping> pingers = new List<Ping>();
    private static int instances = 0;

    private static object @lock = new object();

    private static int result = 0;
    private static int timeOut = 250;

    private static int ttl = 5;

    public static void Main()
    {
        string baseIP = "192.168.1.";

        Console.WriteLine("Pinging 255 destinations of D-class in {0}*", baseIP);

        CreatePingers(255);

        PingOptions po = new PingOptions(ttl, true);
        System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
        byte[] data = enc.GetBytes("abababababababababababababababab");

        SpinWait wait = new SpinWait();
        int cnt = 1;

        Stopwatch watch = Stopwatch.StartNew();

        foreach (Ping p in pingers) {
            lock (@lock) {
                instances += 1;
            }

            p.SendAsync(string.Concat(baseIP, cnt.ToString()), timeOut, data, po);
            cnt += 1;
        }

        while (instances > 0) {
            wait.SpinOnce();
        }

        watch.Stop();

        DestroyPingers();

        Console.WriteLine("Finished in {0}. Found {1} active IP-addresses.", watch.Elapsed.ToString(), result);
        Console.ReadKey();

    }

    public static void Ping_completed(object s, PingCompletedEventArgs e)
    {
        lock (@lock) {
            instances -= 1;
        }

        if (e.Reply.Status == IPStatus.Success) {
            Console.WriteLine(string.Concat("Active IP: ", e.Reply.Address.ToString()));
            result += 1;
        } else {
            //Console.WriteLine(String.Concat("Non-active IP: ", e.Reply.Address.ToString()))
        }
    }


    private static void CreatePingers(int cnt)
    {
        for (int i = 1; i <= cnt; i++) {
            Ping p = new Ping();
            p.PingCompleted += Ping_completed;
            pingers.Add(p);
        }
    }

    private static void DestroyPingers()
    {
        foreach (Ping p in pingers) {
            p.PingCompleted -= Ping_completed;
            p.Dispose();
        }

        pingers.Clear();

    }

}

And VB.net code:

Imports System.Net.NetworkInformation
Imports System.Threading

Module Module1

    Private pingers As New List(Of Ping)

    Private instances As Integer = 0
    Private lock As New Object

    Private result As Integer = 0

    Private timeOut As Integer = 250
    Private ttl As Integer = 5

    Sub Main()

        Dim baseIP As String = "192.168.1."
        Dim classD As Integer = 1

        Console.WriteLine("Pinging 255 destinations of D-class in {0}*", baseIP)

        CreatePingers(255)

        Dim po As New PingOptions(ttl, True)
        Dim enc As New System.Text.ASCIIEncoding
        Dim data As Byte() = enc.GetBytes("abababababababababababababababab")

        Dim wait As New SpinWait
        Dim cnt As Integer = 1

        Dim watch As Stopwatch = Stopwatch.StartNew

        For Each p As Ping In pingers
            SyncLock lock
                instances += 1
            End SyncLock

            p.SendAsync(String.Concat(baseIP, cnt.ToString()), timeOut, data, po)
            cnt += 1
        Next

        Do While instances > 0
            wait.SpinOnce()
        Loop

        watch.Stop()

        DestroyPingers()

        Console.WriteLine("Finished in {0}. Found {1} active IP-addresses.", watch.Elapsed.ToString(), result)
        Console.ReadKey()

    End Sub

    Sub Ping_completed(s As Object, e As PingCompletedEventArgs)

        SyncLock lock
            instances -= 1
        End SyncLock

        If e.Reply.Status = IPStatus.Success Then
            Console.WriteLine(String.Concat("Active IP: ", e.Reply.Address.ToString()))
            result += 1
        Else
            'Console.WriteLine(String.Concat("Non-active IP: ", e.Reply.Address.ToString()))
        End If

    End Sub

    Private Sub CreatePingers(cnt As Integer)

        For i As Integer = 1 To cnt
            Dim p As New Ping
            AddHandler p.PingCompleted, AddressOf Ping_completed
            pingers.Add(p)
        Next
    End Sub
    Private Sub DestroyPingers()

        For Each p As Ping In pingers
            RemoveHandler p.PingCompleted, AddressOf Ping_completed
            p.Dispose()
        Next

        pingers.Clear()

    End Sub

End Module

Solution 2:

Please refer to This link about Asynchronous Client Socket to learn how to ping faster.

Edit: A quick snippet on how to accomplish this:

private static void StartClient() {
        // Connect to a remote device.
        try {
            // Establish the remote endpoint for the socket.
            // The name of the 
            // remote device is "host.contoso.com".
            IPHostEntry ipHostInfo = Dns.Resolve("host.contoso.com");
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);

            // Create a TCP/IP socket.
            Socket client = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // Connect to the remote endpoint.
            client.BeginConnect( remoteEP, 
                new AsyncCallback(ConnectCallback), client);
            connectDone.WaitOne();

            // Send test data to the remote device.
            Send(client,"This is a test<EOF>");
            sendDone.WaitOne();

            // Receive the response from the remote device.
            Receive(client);
            receiveDone.WaitOne();

            // Write the response to the console.
            Console.WriteLine("Response received : {0}", response);

            // Release the socket.
            client.Shutdown(SocketShutdown.Both);
            client.Close();

        } catch (Exception e) {
            Console.WriteLine(e.ToString());
        }
    }

Taken from this Microsoft documentation.