14

I am trying to do this C#. I need to find all ip address that are active in my network and show them in a list. I can ping all available (1...255) ip address in a network. But I want to make this process faster.

Mike Pennington
  • 41,899
  • 19
  • 136
  • 174
Mehbube Arman
  • 472
  • 1
  • 7
  • 18
  • 2
    If you want to make it faster, ping all IPs at the same time: `Ping.SendAsync`. – igrimpe Nov 21 '12 at 11:22
  • I have just ran a command of pinging like this `for /l %n in (1,1,255) do ping 192.168.10.%x` with process.start() and then later read the arp table entry find each ip address in the network. but this very slow. Need to make this fast. – Mehbube Arman Nov 21 '12 at 11:25
  • @MehbubeArman, how many IP addresses are possible in the network and what is "fast enough" – Mike Pennington Nov 21 '12 at 11:57
  • @MehbubeArman I provided a cut-and-paste ready code in my answer. see if that works for you. –  Nov 21 '12 at 12:49
  • 1
    Get your netmask and perform a [broadcast ping](http://www.xsanity.com/article.php/2007062607504287), e.g. `ping 192.168.0.255`. However remember that firewalls may decide to ignore broadcast pings, or to ignore *any* sort of ping period. – vladr Nov 23 '12 at 09:19

5 Answers5

16

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
1

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.

TheGeekZn
  • 3,696
  • 10
  • 55
  • 91
  • thanks NewAmbition. But I was looking for an alternative to pinging all – Mehbube Arman Nov 21 '12 at 11:39
  • 1
    why are you looking for an alternative? (Even then, you never stated that in your question) - Pinging will allow you to see if an IP is up or not.. – TheGeekZn Nov 21 '12 at 11:40
  • 2
    If there is no central point of reference like a domain server/dns server with which hosts register you are going to have to reach out to all candidate addresses and see if there is anything there, ping is the way to do this. – Alex K. Nov 21 '12 at 11:48
1

if you want to go the ARP route, you can simply send out ARP requests for all adresses, wait a bit, and look into the ARP table of your host

this may help

http://www.codeguru.com/cpp/i-n/internet/internetprotocolip/article.php/c6153/How-to-Get-an-ARP-Table-with-an-IP-Helper-API.htm

Dr. Wummi
  • 111
  • 7
0
    public static void NetPing()
    {            
        Ping pingSender = new Ping();
        foreach (string adr in stringAddressList)
        {
           IPAddress address = IPAddress.Parse(adr);
           PingReply reply = pingSender.Send (address);

           if (reply.Status == IPStatus.Success)
           {
                //Computer is active
           }
           else
           {
                //Computer is down
           }
        }  
    }
CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
-3

http://www.advanced-ip-scanner.com/. this a tool you can use to see what ip's are active on your network. also what type of network hardware that PC uses.

Louis
  • 134
  • 1
  • 3
  • 16