我已经使用JPCAP为cpature ping编写了一个代码片段。我写的代码如下:
while (true) {
try {
PacketCapture m_pcap;
m_pcap = new PacketCapture();
m_pcap.open("\\Device\\NPF_{007262BD-....-7EE83D72EBEA}",true);//param 1 is actual device ID
m_pcap.setFilter("proto ICMP", true);
pktlistener a = new pktlistener(); //handles the packet
m_pcap.addPacketListener(a);
System.out.println("going to sleep");
Thread.sleep(1 * 1000);// Waiting for 1 second before ending capture
System.out.println("woken up");
m_pcap.removePacketListener(a);
m_pcap.endCapture();
m_pcap.close();
a = null;
m_pcap = null;
} catch (Exception e) {
e.printStackTrace();
}
}
现在上面的代码每隔一秒就开始一次新的捕获。上面的问题是在循环运行10次之后,它会抛出异常:
Exception in thread "Thread-6" java.lang.Error: Too many instances, exceeds 10
at net.sourceforge.jpcap.capture.PacketCapture.<init>(PacketCapture.java:51)
Q1。我该如何防止这种情况。我需要每秒开始一个新的PacketCapture。
Q2。有没有其他更简单的方法来捕获通过java在系统上收到的ping消息?
答案 0 :(得分:0)
您不能使用PacketCapture
的构造函数十次以上。此行为是硬编码的,因为构造函数如下所示:
/**
* Create a new packet capture instance.
*/
public PacketCapture() {
if (nextInstance >= INSTANCE_MAX) {
throw new Error("Too many instances, exceeds " + INSTANCE_MAX);
}
instanceNum = nextInstance++;
}
要捕获ping请求,您应该尝试以下代码
public class Main {
public static void main(String[] args) throws CaptureDeviceLookupException {
Capture cap = new Capture();
cap.doCapture();
}
}
class PingListener implements PacketListener {
@Override
public void packetArrived(Packet packet) {
try {
// only ICMP packages
if (packet instanceof ICMPPacket) {
ICMPPacket tcpPacket = (ICMPPacket) packet;
int data = tcpPacket.getMessageCode();
// only echo request packages
if (data == ICMPMessages.ECHO) {
// print source and destination.
String srcHost = tcpPacket.getSourceAddress();
String dstHost = tcpPacket.getDestinationAddress();
System.out.println("Ping from: " + srcHost + " to " + dstHost);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Capture {
public void doCapture() {
// create capture instance
PacketCapture capture = new PacketCapture();
// add listener that handles incomming and outgoing packages
PingListener pingListener = new PingListener();
capture.addPacketListener(pingListener);
// m_pcap.setFilter("filter here or in handler", true);
try {
capture.open("\\Device\\NPF_{...}", true); // connect capture to device
while (true) {
capture.capture(1); // capture one package
}
} catch (Exception e) {
e.printStackTrace(); // exception during capture or handling of
// packages
} finally {
// technically never reached as the loop goes on forever.
// if loop terminates after a while then:
// remove listener
capture.removePacketListener(pingListener);
// end capture (only necessary, if PacketCapture still waits for
// other packages)
capture.endCapture();
// close connection to capture device
capture.close();
}
}
}
我认为对班级PacketCapture
存在误解。它实际上并不捕获一个包,然后被丢弃。它会打开与要捕获包的设备的连接,然后只要您保持该连接就开始侦听。然后,您可以通过调用n
开始捕获capture.capture(n)
个包。对于在“捕获”阻止程序时到达的每个程序包,将调用侦听器。
或者,您可以删除while循环并使用capture.capture(-1)
。这将永远阻止您的程序,直到您关闭其他设备的捕获。