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上它提供了一个例外
答案 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()); }
}
}
}