2013-05-31 42 views
0

我已經使用JPCAP將一段代碼片段寫入了cpature ping。我寫的代碼如下:捕獲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。 Q2302。有沒有其他更簡單的方法來捕獲通過Java在系統上收到的ping消息?

+0

瀏覽此鏈接。它可以幫助你。 [1]:http://stackoverflow.com/questions/4452814/how-to-send-ping6-request-using-java-library-jpcap?rq=1 –

回答

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的誤解。它實際上並沒有捕獲一個包,然後被丟棄。它打開一個連接到你想要捕獲包的設備,然後開始監聽,只要你保持該連接。您然後通過致電capture.capture(n)開始捕獲n包。對於每個包到達,而「捕獲」阻止你的程序,監聽器被調用。

或者,您可以刪除while循環並使用capture.capture(-1)。這將永遠阻止您的程序,直到您關閉從另一個設備捕獲。

+0

我實際上是發送HTTP請求到服務器。當服務器收到請求時,它可能會或可能無法ping我的機器。所以我需要跟蹤哪個請求導致ping。爲了實現這個,我創建了具有HTTP請求作爲參數的構造函數的實際PktListener(我的代碼)。在packetArrived方法中,如果ping來了,我打印HTTP請求(從本地變量到這個類)到一個文件,從而識別哪個請求產生了ping。因此,我需要每秒開始一個新實例。 – Rishabh

+0

@Rishabh編輯答案,以配合你的問題。我認爲PacketCapture的功能存在誤解。 – DKM

+0

該代碼工作正常。它一定會解決我的問題。謝謝! – Rishabh