找到特定端口号打开的网络上所有设备的IP地址

时间:2016-10-22 05:17:30

标签: java windows networking ip port

 Socket socket = new Socket();

try {
Process process = Runtime.getRuntime().exec("arp -i en0 -a -n");
process.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

while (reader.ready()) {
    String ip = reader.readLine();
    ip = ip.substring(3, ip.indexOf(')'));

    try {
        socket.connect(new InetSocketAddress(ip, 1234), 1000);
        System.out.println("Found socket!");
    } catch (ConnectException | SocketTimeoutException ignored) {

    }
}

if (socket == null) {
    System.err.println("Could not find socket.");
}
} catch (Exception e) {
e.printStackTrace();
}

我发现这个代码在stackoverflow上它是用于mac而我需要找到一个替代windows O.S。 在Windows上它提供了一个例外

2 个答案:

答案 0 :(得分:1)

嗯,首先,我不相信Windows中使用的ARP(Address Resolution Protocol)有 -i 参数。 -n 参数有 -N ,而 N 为大写。显然ARP命令行是错误的,您应该使用Windows命令提示符窗口自行检查。只需在命令提示符窗口中输入 arp ,即可查看ARP的所有可用参数。

要检索您只需要提供的ARP表:“ arp -a ”,但您收到的费用超出了您的讨价还价范围,您将需要解析所需的IP地址到您连接的设备,我认为这将是动态IP。以下是Windows 10框中的ARP表示例:

Interface: 192.168.0.25 --- 0x2
  Internet Address      Physical Address      Type
  192.168.0.69          25-ad-42-bb-bd-65     dynamic
  192.168.0.254         b8-29-34-f9-27-65     dynamic
  192.168.0.255         ff-ff-ff-ff-ff-ff     static
  224.0.0.2             01-00-5e-00-00-02     static
  224.0.0.22            01-00-5e-00-00-16     static
  224.0.0.251           01-00-5e-00-00-fb     static
  224.0.0.252           01-00-5e-00-00-fc     static
  224.0.0.253           01-00-5e-00-00-fd     static
  239.255.255.250       01-00-5e-7f-ff-fa     static
  239.255.255.253       01-00-5e-7f-ff-fd     static
  255.255.255.255       ff-ff-ff-ff-ff-ff     static

如前所述,我相信您想要的是动态IP地址,但无论您想要什么,都需要您解析并清理数据。当您解析出所需的数据时,最好将其放入 List 数组中。下面我提供了一个小型的可运行程序,它可以在您的Windows计算机上运行:

package networkdevices;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;


public class NetworkDevices {
    private static int port = 1234;

    public static void main(String[] args) {
        getNetworkDevices();
    }

    private static void getNetworkDevices(){
        Socket socket = new Socket();

        try {
            Process process = Runtime.getRuntime().exec("arp -a"); 
            process.waitFor();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String ip = null;
            List<String> ipList = new ArrayList<>(); // List<> Array to hold dynamic IP Addresses
            while ((ip = reader.readLine()) != null) {
                ip = ip.trim();     // Trim the data
                if (!ip.equals("")) { 
                    if (!ip.equals("")) {
                        // Remove all the unwanted spaces between data provided by 
                        // the ARP Table when it is generated.
                        while (ip.contains("  ")) { ip = ip.trim().replace("  ", " "); }
                        // Split each data line into a String Array for processing
                        String[] dataArray = ip.split(" ");
                        // For console output display only...
                        if (dataArray[0].toLowerCase().startsWith("interface:")) {
                            System.out.println("Locating Devices Connected To: " + dataArray[1]);
                        }
                        // If the data line contains the word "dynamic"
                        // then add the IP address on that line to the 
                        // List<> Array...
                        if (dataArray[2].equalsIgnoreCase("dynamic")) {
                            ipList.add(dataArray[0]);
                            // For console output display only...
                            System.out.println("Device Located On IP: " + dataArray[0]);
                        }
                    }
                }
            }
            // Close the Reader
            reader.close();

            // try to connect to the device....
            // You'll need to play with this.
            try {
                for (int i = 0; i < ipList.size(); i++) {
                    ip = ipList.get(i);
                    socket.connect(new InetSocketAddress(ip, port), 1000);
                    if (socket == null) {
                        System.err.println("Could not find socket.");
                    }
                    else { 
                        System.out.println("Found socket for: " + ip); 
                    }
                    socket.close();
                }
            } catch (ConnectException | SocketTimeoutException ex) {
                System.out.println("\nSOCKET ERROR - " + ex.getMessage());
            }
        } catch (IOException | InterruptedException e) { 
            System.out.println("\nPROCESS/READER ERROR - " + e.getMessage()); 
        }
    }
}

答案 1 :(得分:0)

这个补充的答案是关于套接字连接的第二个问题。这应该是作为另一个主题开始的,但从来没有......

不幸的是,它不像翻转Socket对象那样简单,并期望它能够连接到你找到的设备。每个设备都需要考虑几件事情,例如防火墙保护,防病毒保护,设备本身的连接要求,如端口号等等。您还可以更成功地与80等公共端口建立连接。而不是像1234那样模糊不清的东西。

在我看来,您的Socket连接应该更加健壮,以便至少接收确认您的连接可能失败或成功的原因。事实上(IMO),您的Socket连接应该完全由不同的方法完成。

我再次为您提供了另一个可运行的示例,但这次我做了一些更改并添加了更多方法。我做的第一个更改是将 getNetworkDevices() 方法重命名为 getNetworkDeviceIPs(),并让它实际返回字符串List&lt;&gt;检测到的设备IP的数组。第二个变化是我从 getNetworkDeviceIPs()方法中删除了Socket连接代码,并将Socket Connection代码放入另一个名为 connectToDevices()的方法中。

如前所述,我在下面显示的新runnable示例中添加了几个新方法。第一种方法命名为 getDeviceName(),并且此方法从List&lt;&gt;传递IP地址。从 getNetworkDeviceIPs()方法检索的数组。列表的元素中包含的每个IP&lt;&gt;迭代数组并通过此方法检查,以便在控制台中显示该设备的主机名(以及IP地址)。

第二种新方法(如前所述)名为 connectToDevices(),它传递给List&lt;&gt;从 getNetworkDeviceIPs()方法检索的数组。此方法将尝试打开与字符串列表中包含的每个设备IP地址的套接字连接&lt;&gt;阵列。此方法当前不返回任何内容(它是 void ),但是在控制台窗口中是否显示连接结果是否成功。您可以修改此方法,以便以您喜欢的方式返回结果。

以下是演示上述所有项目的新示例runnable:

package networkdevices;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;


public class NetworkDevices {
    public static int port = 80;

    public static void main(String[] args) {
        //Get devices from system ARP Table and
        // place their IP's into a List<> Array...
        List<String> ipList = getNetworkDeviceIPs(port);

        // Iterate trough the List<> Array and display
        // Device names stored within with the getDeviceName()
        // method...
        System.out.println("\nListing Device Names - Please Wait...");
        for (int i = 0; i < ipList.size(); i++) {
            System.out.println(getDeviceName(ipList.get(i)));
        }

        // Try to connect to each Device that is storred
        // within the List<> Array....
        System.out.println("\nTrying To Connect To Devices...");
        connectToDevices(ipList, port);
    }

    private static List<String> getNetworkDeviceIPs(int portNumber){
        Socket socket = new Socket();
        List<String> ipList = new ArrayList<>(); // List<> Array to hold IP Addresses

        try {
            Process process = Runtime.getRuntime().exec("arp -a"); 
            process.waitFor();
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String ip = null;
            while ((ip = reader.readLine()) != null) {
                ip = ip.trim();     // Trim the data
                if (!ip.equals("")) { 
                    if (!ip.equals("")) {
                        // Remove all the unwanted spaces between data provided by 
                        // the ARP Table when it is generated.
                        while (ip.contains("  ")) { ip = ip.trim().replace("  ", " "); }
                        // Split each data line into a String Array for processing
                        String[] dataArray = ip.split(" ");
                        // For console output display only...
                        if (dataArray[0].toLowerCase().startsWith("interface:")) {
                            System.out.println("Locating Devices Connected To: " + dataArray[1]);
                        }
                        // If the data line contains the word "dynamic"
                        // then add the IP address on that line to the 
                        // List<> Array...
                        if (dataArray[2].equalsIgnoreCase("dynamic")) {
                            ipList.add(dataArray[0]);
                            // For console output display only...
                            System.out.println("Device Located On IP: " + dataArray[0]);
                        }
                    }
                }
            }
            // Close the Reader
            reader.close();
        } 
        catch (IOException | InterruptedException e) { 
            System.out.println("\nPROCESS/READER ERROR - " + e.getMessage()); 
        }
        return ipList;
    }

    private static String getDeviceName(String localIP) {
        String result = "";
        try {
            InetAddress address = InetAddress.getByName(localIP);
            if (address.isReachable(500)) {
                // Device is turned on and can be pinged!;
                result = address.toString();
            }
            else if (!address.getHostAddress().equals(address.getHostName())) {
                // Device is identified in a DNS lookup!
                result = address.toString();
            }
            else {
                // if you keep getting something like "Unknown Device!/192.168.0.5 then the host
                // address and host name are the same, meaning the host name could not be resolved.
                // This means that either your router just isn't storing the information OR those 
                // devices just choose not to submit their host name to the router, and that is why
                // you will continually get this message. Apparently, there is no way around this 
                // because those device names literally aren't stored anywhere.
                result = "Unknown Device!/" + address.toString().substring(0,address.toString().indexOf("/"));
            }
        } 
        catch (UnknownHostException ex) { System.out.println(ex.getMessage()); } 
        catch (IOException ex) { System.out.println(ex.getMessage()); }

        return result;
    }

    private static void connectToDevices(List<String> localIPAddresses, int port) {
        // try to connect to the device(s)....
        // You'll need to play with this.
        for (int i = 0; i < localIPAddresses.size(); i++) {
            if (i > 0) { System.out.println(""); }
            try {
                System.out.println("Connecting to: " + localIPAddresses.get(i) + " on port: " + 
                                   port + " - Please Wait...");
                Socket thisSystem = new Socket(localIPAddresses.get(i), port);

                System.out.println("Just connected to: " + thisSystem.getRemoteSocketAddress());
                OutputStream outToServer = thisSystem.getOutputStream();
                DataOutputStream out = new DataOutputStream(outToServer);

                out.writeUTF("Hello from: " + thisSystem.getLocalSocketAddress());
                InputStream inFromServer = thisSystem.getInputStream();
                DataInputStream in = new DataInputStream(inFromServer);

                System.out.println("Device says " + in.readUTF());
                thisSystem.close();
            }
            catch(IOException e) { System.out.println(e.getLocalizedMessage()); }
        }
    }
}