0

我正在尝试制作一个程序,女巫会自动发现一个 Android 设备(运行 Android 4.2 的 Galaxy S2)并开始与它通信。

这个想法是向本地网络上连接的所有设备(最多 2 到 6 个设备)发送一个数据包,而回答请求的那个就是我正在寻找的那个。首先,我 ping 所有可能的本地 IP 地址并将数据包发送到成功的 ping。

从 C# ping 设备时遇到问题。我通过命令行以正常方式对其进行 ping 操作没有问题,但是使用代码执行此操作可能有 30% 的时间有效,其余时间我得到 11050 回复(女巫我没有成功破译蜜蜂)

这是我的 ping 代码:

    public static bool PingIt(string IP)
    {
        // Get an object that will block the main thread.
        AutoResetEvent waiter = new AutoResetEvent(false);
        Ping pingSender = new Ping();
        PingOptions options = new PingOptions();
        // Use the default Ttl value which is 128, 
        // but change the fragmentation behavior. 
        options.DontFragment = true;
        options.Ttl = 128;

        // When the PingCompleted event is raised,
        // the PingCompletedCallback method is called.
        pingSender.PingCompleted += new PingCompletedEventHandler(PingCompletedCallback);

        // Create a buffer of 32 bytes of data to be transmitted. 
        string data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        byte[] buffer = Encoding.ASCII.GetBytes(data);
        int timeout = 5000;
        //PingReply reply = pingSender.Send(IP, timeout, buffer, options);

        try
        {
            pingSender.SendAsync(IP, timeout, buffer, options, waiter);
            //pingSender.SendAsync(IP, timeout, IP);
        }
        catch (PingException ex)
        {
            Console.WriteLine(ex.InnerException);
            return false;
        }

        return true;
    }

和回调:

    private static void PingCompletedCallback(object sender, PingCompletedEventArgs e)
    {
        // If the operation was canceled, display a message to the user.
        if (e.Cancelled)
        {
            Console.WriteLine("Ping canceled.");
            // Let the main thread resume. 
            // UserToken is the AutoResetEvent object that the main thread 
            // is waiting for.
            ((AutoResetEvent)e.UserState).Set();
        }
        // If an error occurred, display the exception to the user.
        if (e.Error != null)
        {
            Console.WriteLine("Ping failed:");
            Console.WriteLine(e.Error.ToString());
            // Let the main thread resume. 
            ((AutoResetEvent)e.UserState).Set();
        }

        PingReply reply = e.Reply;
        Console.WriteLine(reply.Address.ToString() + " " + reply.Status.ToString());

        // Let the main thread resume.
        ((AutoResetEvent)e.UserState).Set();

        lock(lockObj)
        {
            pingProgress++;

            //if (reply.Status == IPStatus.Success)
                //availableDevices.Add(reply.Address.ToString());
        }
    }

输出只是 ping 的结果。我也试过关闭防火墙,但没有帮助。有什么建议么?

4

1 回答 1

0

这是一个老问题,所以我猜你已经找到了解决方案或解决方法,但无论如何这里有一些建议。

我认为你的逻辑有错误。您设置了 AutoResetEvent 以等待,并使用 SendAsync,这是一个非阻塞调用,但您从不等待 AutoResetEvent,因此您的程序只是继续执行其他操作。在回调中有一条注释“让主线程恢复”。你设置了 AutoResetEvent,但没有人在等待它,对吧?

接下来,“ping 所有可能的本地 IP 地址”的想法听起来很糟糕。网络管理员不会对你好感。

我的建议(这可能不可行,不知道您的设置是什么)是您的 Android 应用程序应该向您的 PC 程序发送一个“你好,我还活着(这是我的 IP 地址)”消息一次尽管。(不要太频繁,以避免电池耗尽。)您的 PC 程序应该跟踪最近打过招呼的 Android 设备的 10 个 IP 地址。

于 2013-09-22T10:29:03.063 回答