捕获ping包抛出异常(实例太多)



我已经编写了一个代码片段来使用JPCAP来捕获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消息?

不能使用PacketCapture的构造函数超过10次。这种行为是硬编码的,构造函数看起来像这样:

/**
 * 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类存在误解。它实际上并没有捕获一个包,然后被丢弃。它打开一个连接到你想要捕获包的设备,然后开始监听,只要你保持这个连接。然后通过调用capture.capture(n)开始捕获n包。当"capture"阻塞程序时,对于每个到达的包,将调用侦听器。

或者,您可以放弃while循环并使用capture.capture(-1)。这将永远阻塞您的程序,直到您从另一个设备关闭捕获。

最新更新