java - 如何自动找到网络IP地址并连接到它?

标签 java android android-studio

我使用的是 Android Studio 1.3 今天我将在字符串中提供手动 IP 地址。

在我的笔记本电脑上,我正在运行一个网络服务器。 在我的 Android Studio 上我正在运行一个客户端。 问题是我当前正在使用硬编码的 IP 地址手动连接到 Web 服务器。

我的电脑房里有一个路由器,我用笔记本电脑连接到路由器网络。 例如,我的笔记本电脑 IP 地址是 10.0.0.3,如果我登录到路由器设置,我可以看到笔记本电脑已连接。

问题是有时如果我的电脑由于某种原因关闭,下次它可能会使用不同的 IP 地址连接到我的路由器。

在 Android Studio 的 Java 端我做了:

package com.test.webservertest;

public class MainActivity extends ActionBarActivity
{
    private static final int MY_DATA_CHECK_CODE = 0;
    public static MainActivity currentActivity;
    TextToSpeech mTts;
    private String targetURL;
    private String urlParameters;
    private Button btnClick;
    private String clicking = "clicked";
    private String[] ipaddresses = new String[]{
        "http://10.0.0.3:8098/?cmd=nothing"};
    private String iptouse = "";
    private TextView text;
    private boolean connectedtoipsuccess = false;
    private int counter = 0;
    private NotificationCompat.Builder mbuilder;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        addListenerOnButton();
        currentActivity = this;
        initTTS();
    }

然后在addListenerOnButton中:

public void addListenerOnButton()
{

btnClick = (Button) findViewById(R.id.checkipbutton);

        btnClick.setOnClickListener(new OnClickListener()
        {
            byte[] response = null;
            @Override
            public void onClick(View arg0)
            {

                text = (TextView) findViewById(R.id.textView2);

                Thread t = new Thread(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        for (int i = 0; i < ipaddresses.length; i++)

                        {
                                counter = i;
                                try
                                {
                                    response = Get(ipaddresses[i]);
                                }
                                catch (Exception e)
                                {
                                    String err = e.toString();
                                }

                                if (response!=null)
                                {


                                    try
                                    {
                                        final String a = new String(response, "UTF-8");



                                        text.post(new Runnable()
                                        {
                                            @Override
                                            public void run()
                                            {
                                                text.setText(a + " Oמ " + ipaddresses[counter]);

                                                String successconnected = null;
                                                successconnected = "Successfully connected";
                                                textforthespeacch = successconnected;
                                                MainActivity.currentActivity.initTTS();
                                            }
                                        });
                                        iptouse = ipaddresses[i].substring(0,ipaddresses[i].lastIndexOf("=")+1);
                                        connectedtoipsuccess = true;
                                        Logger.getLogger("MainActivity(inside thread)").info(a);
                                    } catch (UnsupportedEncodingException e)
                                    {
                                        e.printStackTrace();
                                        Logger.getLogger("MainActivity(inside thread)").info("encoding exception");
                                    }

                                    Logger.getLogger("MainActivity(inside thread)").info("test1");
                                    break;
                                }
                                else
                                {

                                }

                        }
                        counter = 0;
                        if (response == null)
                        {
                            text.post(new Runnable()
                            {
                                @Override
                                public void run()
                                {
                                    text.setText("Connection Failed");
                                    String successconnected = null;
                                    successconnected = "connection failed";
                                    textforthespeacch = successconnected;
                                    MainActivity.currentActivity.initTTS();
                                }
                            });
                        }
                    }
                });
                t.start();
            }
        });
    }
}

现在在我的电脑室中,笔记本电脑的 IP 地址是 10.0.0.3 我还将我的笔记本电脑添加到路由器作为笔记本电脑 Mac 的静态 IP 地址。

在我的 Java 代码中,我有一个 10.0.0.3 的字符串,但如果我将笔记本电脑和 Android 设备带到客厅,那里有一个不同的网络,笔记本电脑的 IP 地址将是其他内容。

我想要做的是,当我单击按钮时,它只会尝试连接到字符串中给定的 IP 地址,但我希望它会自动检测路由器中的笔记本电脑 IP 地址并连接到它。

所以我不需要一直在我的java代码中更改字符串中的IP地址。

我认为它被称为 umdp 之类的东西,不确定。

最佳答案

您可以选择查询 Android 设备的 ARP缓存。不幸的是,由于这只是您的 Android 设备已识别的所有设备的列表,因此可能不是 100% 完整。因此,您可以做的是获取 IP,然后 ping 该子网上所有可能的 IP,强制更新缓存。从那里,您可以在缓存中搜索笔记本电脑的 MAC 地址并读取其 IP。这是我整理的一些(未经测试的)代码,应该可以帮助您走上正确的道路:

private static void refereshArp(Context ctx){
    //IP aquisition from http://stackoverflow.com/a/6071963/1896516
    WifiManager wm = (WifiManager) ctx.getSystemService(WIFI_SERVICE);
    String ip = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
    String[] parts = ip.split(".");
    String subnet = parts[0] + "." + parts[1] + "." + parts[2] + ".";
    Runtime rt = Runtime.getRuntime();
    for(int i=0; i<256; i++){
        try{
            rt.exec("ping -c1 " + subnet + i)
        }catch(IOException e){
            continue;
        }
    }

}

//Adapted from http://www.flattermann.net/2011/02/android-howto-find-the-hardware-mac-address-of-a-remote-host/
private static String getIpFromMac(String mac) {
    if (mac == null)
        return null;
    BufferedReader br = null;
    try {
        br = new BufferedReader(new FileReader("/proc/net/arp"));
        String line;
        while ((line = br.readLine()) != null) {
            String[] splitted = line.split(" +");
            if (splitted != null && splitted.length >= 4 && mac.equals(splitted[3])) {
                // return the ip of the device
                return splitted[0];
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    return null;
}

如果您使用笔记本电脑的 MAC 调用 refreshArp(),然后调用 getIpFromMac(),您应该获得其 IP,只要它们位于同一网络上。同样,我还没有测试过这段代码,因此可能需要一些调整才能使其正常工作。

关于java - 如何自动找到网络IP地址并连接到它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32214437/

相关文章:

java - 在文本文件中查找特定单词并对其进行计数

java - 如何使用 JSOUP 提取 css 样式

java - Eclipse 提供了 Java API 浏览功能,但是如何在 Java API 中搜索类名或成员名呢?

Android:在服务器上播放 mp3 文件时出现异常。

层列表中的 Android 项目大小

android - Android Studio启动模拟器报错

java - setOnClickListener(android.view.View$OnClickListener)' 在空对象引用上

java - 无法在 Samsung A5 (2016) 上使用 Toast

android - 如何构建 _just_ libwebcore.so 而不是整个 froyo 源

android - 广播怎么可能是 "malicious"?