12

我正在尝试做这个 C#。我需要找到在我的网络中活动的所有 IP 地址并将它们显示在列表中。我可以 ping 网络中所有可用的 (1...255) ip 地址。但我想让这个过程更快。

4

5 回答 5

15

此代码在大约 1 秒内扫描了我的网络 255 个 D 级网段。我在 VB.net 中编写它并将其翻译成 C#(如果有任何错误,请致歉)。将其粘贴到控制台项目中并运行。根据需要进行修改。

注意:代码还没有准备好生产,需要改进,尤其是实例计数(尝试TaskFactory用 aBlockingCollection来实现)。

如果结果不稳定,请修改 ttl(生存时间)和超时。

运行代码会得到如下结果:

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#代码:

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();

    }

}

和 VB.net 代码:

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
于 2012-11-21T12:35:20.020 回答
1

请参阅有关异步客户端套接字的此链接以了解如何更快地 ping。

编辑:有关如何完成此操作的快速片段:

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());
        }
    }

取自此 Microsoft 文档。

于 2012-11-21T11:23:02.570 回答
0

如果你想走 ARP 路由,你可以简单地发送所有地址的 ARP 请求,稍等一下,然后查看你主机的 ARP 表

这可能会有所帮助

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

于 2012-11-21T13:40:25.533 回答
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
           }
        }  
    }
于 2012-11-21T12:10:07.497 回答
-3

http://www.advanced-ip-scanner.com/。这是一个工具,您可以使用它来查看您的网络上哪些 ip 处于活动状态。以及PC使用什么类型的网络硬件。

于 2012-11-21T11:33:34.853 回答