这个添加的答案是针对您关于套接字连接的第二个问题。这应该完全作为另一个主题开始,但绝不会少......
不幸的是,它不像放下一个 Socket 对象并期望它连接到您找到的设备那么简单。每个设备需要考虑几件事,例如防火墙保护、防病毒保护、设备本身的连接要求(如端口号等)。使用 80 等通用端口连接也会获得更多成功而不是像 1234 这样晦涩的东西。
在我看来,您的 Socket 连接应该更健壮一些,以便至少收到关于您的连接可能失败或成功的原因的确认。事实上(IMO),您的 Socket 连接应该完全通过不同的方法完成。
我再次为您提供另一个可运行的示例,但这次我做了一些更改并添加了更多方法。我所做的第一个更改是将 getNetworkDevices() 方法重命名为 getNetworkDeviceIPs() 并让它实际返回一个字符串 List Array检测到的设备 IP。第二个更改是我从 getNetworkDeviceIPs() 方法中删除了 Socket 连接代码,并将 Socket 连接代码放入名为 connectToDevices() 的不同方法中。
如前所述,我在如下所示的新可运行示例中添加了几个新方法。第一个方法名为 getDeviceName(),该方法从 getNetworkDeviceIPs() 方法检索的 List 数组中传递一个 IP 地址。 List 数组元素中包含的每个 IP 都通过此方法进行迭代和检查,以便在控制台中显示该设备的主机名(以及 IP 地址)。
第二个新方法(正如我们之前提到的)名为 connectToDevices(),它传递从 getNetworkDeviceIPs() 方法检索到的 List 数组。此方法将尝试打开与字符串列表 数组中包含的每个设备 IP 地址的套接字连接。此方法当前不返回任何内容(它是 void),但会在控制台窗口中显示连接结果,以了解它是否成功。您当然可以修改此方法以返回任何您喜欢的结果。
这是一个新的可运行示例,展示了上述所有项目:
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()); }
}
}
}