本人最近做PC端项目,遇到一个ip地址相关通信方面的问题,经过网上资料的一些查询觉得目前此方法相对较好,特在此做个记录,各位路过的大神,如有更好的方法,麻烦留下解答,让小弟借鉴下.
下面进入正题,首先获取到本机的ip地址,比较简单(主要通过cmd指令arp -a拿到当前电脑所有的缓存地址与ip地址所对应表),如下代码
public class GoodWindowsExec {
@SuppressWarnings("unused")
public static ArrayList<String> exec(String cmdLine) {
ArrayList<String> lines = new ArrayList<>();
try {
String osName = System.getProperty("os.name");
String[] cmd = new String[3];
cmd[0] = "cmd.exe";
cmd[1] = "/C";
cmd[2] = cmdLine;
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
InputStreamReader ir = new InputStreamReader(proc.getInputStream(),"gbk");
LineNumberReader input = new LineNumberReader(ir);
String line = null;
while ((line = input.readLine()) != null){
System.out.println(line);
lines.add(line);
}
// any error???
int exitVal = proc.waitFor();
System.out.println("ExitValue: " + exitVal);
} catch (Throwable t) {
t.printStackTrace();
}
return lines;
}
public static void main(String args[]) {
exec("arp -a");
Enumeration<NetworkInterface> nets = NetworkInterface
.getNetworkInterfaces();
for (NetworkInterface netint : Collections.list(nets))
if (null != netint.getHardwareAddress()) {
List<InterfaceAddress> list = netint.getInterfaceAddresses();
for (InterfaceAddress interfaceAddress : list) {
String localip=interfaceAddress.getAddress().toString();
System.out.println("======="+localip+"===========");
}
}
}
因为我这边的PC客户端需要知道下位机目前的ip地址,而我只知道下位机的主机名,所以我通过得到本机的ip地址,然后遍历ping出局域网下所能Ping通的ip地址然后放入集合中,在遍历出这些地址所对应的主机名匹配,代码如下:
public class IP {
static public HashMap<String,String> ping; // ping 后的结果集
static ArrayList<String> actives = new ArrayList<>();
public HashMap<String,String> getPing() { // 用来得到ping后的结果集
return ping;
}
public static long begin;
// 当前线程的数量, 防止过多线程摧毁电脑
static int threadCount = 0;
public IP() {
ping = new HashMap<String,String> ();
}
public void Ping(String ip) throws Exception {
// 最多30个线程
while (threadCount > 30)
Thread.sleep(50);
threadCount += 1;
PingIp p = new PingIp(ip);
p.start();
}
public void PingAll() throws Exception {
// 首先得到本机的IP,得到网段
String localip = ListNets.getAllLocalIp().get(0).substring(1,ListNets.getAllLocalIp().get(0).length());
int k = 0;
k = localip.lastIndexOf(".");
String ss = localip.substring(0, k + 1);
Controller.IP3 = ss;
for (int i = 1; i <= 255; i++) { // 对所有局域网Ip
String iip = Controller.IP3 + i;
Ping(iip);
}
}
class PingIp extends Thread {
public String ip; // IP
public PingIp(String ip) {
this.ip = ip;
}
public void run() {
try {
Process p = Runtime.getRuntime().exec("ping " + ip + " -w 300 -n 1");
InputStreamReader ir = new InputStreamReader(p.getInputStream(),"gbk");
LineNumberReader input = new LineNumberReader(ir);
// 读取结果行
for (int i = 1; i < 7; i++){
input.readLine();
}
String line = input.readLine();
if (line == null || line.length() < 17 || line.substring(8, 17).equals("timed out"))
ping.put(ip, "None");
else
actives.add(ip);
// 线程结束
threadCount -= 1;
} catch (IOException e) {
}
}
}
public ArrayList<String> getCrIP() throws Exception {
PingAll();
ArrayList<String> crip;
crip = actives;
return crip;
}
public class ConnectThread extends Thread{
@Override
public void run() {
IP ip = new IP();
ArrayList<String> lines =new ArrayList<>();
try {
lines = ip.getCrIP();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
ArrayList<String> ips = new ArrayList<>();
for(String line:lines){
try {
String localip = ListNets.getAllLocalIp().get(0).substring(1,ListNets.getAllLocalIp().get(0).length());
int k = 0;
k = localip.lastIndexOf(".");
String ss = localip.substring(0, k + 1);
Controller.IP3 = ss;
if(line.indexOf(Controller.IP3) ==0){
String[] s = line.trim().split(" ");
ips.add(s[0].trim());
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int i=0;i<ips.size();i++){
byte[] address=toIpByte(ips.get(i));
InetAddress addr;
try {
addr = InetAddress.getByAddress(address);
String hostname = addr.getHostName();
if(hostname.length()>5 && (hostname.indexOf("下位机主机名")==0)){
return;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static byte[] toIpByte(String ip) {
String[] ips=ip.split("\\.");
byte[] address=new byte[ips.length];
for (int i=0;i<ips.length;i++){
address[i]=(byte) Integer.parseInt(ips[i]);
}
return address;
}
public static void main(String[] args) {
ConnectThread c = new ConnectThread();
c.start();
}
}
这种做法就是在启动PC端的时候,pingip的时候启动速度会略慢,会影响到客户的体验,所以希望一些有更好办法的朋友,给小弟留个言,谢谢了!