最近计算机网络课要求做一个Ping功能,用java实现,网上找了很多都是C语言写的,或者是只能ping局域网的主机,最后改了很久,做了一下修改,终于可以ping外网了。这里java要实现链路层的功能就必须要用到jpcap.jar包,jpcap基于wincap,所以必须安装wincap这个软件,还有配置一下jpcap.dll的位置,网上查找一下就可以了。这里的ping发送报文要目的ip地址,这个很容易取得,还有一个便是目的mac地址,网上的大多数都是把mac地址填为ff-ff-ff-ff-ff-ff广播地址,广播只能在局域网内广播,无疑使ping功能毁了。而java很难取得目的外网的mac地址,mac地址不对,便无法传出去,由于外网目的mac地址很难取得,搞了很久也无法取得,最后研究协议后才知道,目的mac地址并不需要直接跟ip对应,你只需要知道你连接的路由器的mac地址,把报文传出去后,后面的路由器会根据协议会自行帮你传送报文到目的ip。
预览图:
下面是获取路由器ip的类:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.lsj.ping;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RouteIpUtils {
public RouteIpUtils() {
}
public String getRouteIP() {
try {
Process pro = Runtime.getRuntime().exec("ipconfig");
BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream(), "gb2312"));
ArrayList rowList = new ArrayList();
String temp;
while((temp = br.readLine()) != null) {
rowList.add(temp);
}
Iterator var5 = rowList.iterator();
while(var5.hasNext()) {
String string = (String)var5.next();
Matcher mc;
if (string.indexOf("默认网关") != -1) {
mc = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}").matcher(string);
if (mc.find()) {
System.out.println("默认网关:" + mc.group());
return mc.group();
}
} else if (string.indexOf("Default Gateway") != -1) {
mc = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}").matcher(string);
if (mc.find()) {
System.out.println("默认网关:" + mc.group());
return mc.group();
}
}
}
System.out.println("默认网关为空");
} catch (IOException var8) {
var8.printStackTrace();
}
return null;
}
}
下面是根据ip获取mac的类,获取路由器mac:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.lsj.ping;
import java.io.InputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FetchMac {
public FetchMac() {
}
public String command(String cmd) throws Exception {
Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
InputStream in = process.getInputStream();