jpcap java 使用

1.jpcap說明與安裝
   JAVA語言雖然在TCP/UDP傳輸方面給予了良好的定義,但對於網絡層如下的控制,倒是無能爲力的。JPCAP擴展包彌補了這一點,jPcap是一個可讓java工做在鏈路層的類庫;固然,它底層仍是使用了本機API經過Jini調用,在javaAPI中獲得數據。JPCAP實際上並不是一個真正去實現對數據鏈路層的控制,而是一箇中間件,JPCAP調用wincap/libpcap,而給JAVA語言提供一個公共的接口,從而實現了平臺無關性。在官方網站上聲明,JPCAP支持FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft Windows 2000/XP等系統。jPcap下載地址:http://netresearch.ics.uci.edu/kfujii/jpcap/doc/index.html; 你能夠從jpcap網站上直接下載它的桌面應用程序進行測試,能夠全面的統計本機的網絡數據流量及收發包數據。
Jpcap is a Java class package that allows Java applications to capture and/or send packets to the network.
Jpcap is based on libpcap/winpcap and Raw Socket API. Therefore, Jpcap is supposed to work on any OS on which libpcap/winpcap has been implemented. Currently, Jpcap has been tested on FreeBSD 3.x, Linux RedHat 6.1, Fedora Core 4, Solaris, and Microsoft Windows 2000/XP.
Jpcap supports the following types of packets: Ethernet, IPv4, IPv6, ARP/RARP, TCP, UDP, and ICMPv4.  Other types of packets are captured as raw packets (i.e., instances of the Packet class) which contains the whole data of the packets.  This allows Java applications to analyze unsupported packet types.
本項目中使用的是jPcap0.6版本,從其網站上下載Source build後,能夠看到其下詳細的目錄結構,源碼,例程及Native lib。
 
         使用 jPcap能夠編寫出功能完備的網絡嗅測程序,本節中,咱們只是使用其很是簡單的一個功能:統計本機每塊網卡上收發數據的總量。
   特別注意:jpcap運行時依賴winCap的類庫,使用前必須在機地安裝winCap(http://www.winpcap.org/若是是在liunx上,則請到http://www.tcpdump.org/下載)。本節中jPcap版本爲0.6,winCap版本爲4.0,運行與win32系統上。 )(
 
 
2.jPcap小試:顯示本機網絡接口詳情
jPcap中的API很是簡單,可查看其在線文檔:http://netresearch.ics.uci.edu/kfujii/jpcap/doc/javadoc/index.html。固然,要靈活的使用,你必須有良好的tcp/ip協議知識基礎,對經常使用的3個關鍵類,簡介以下:
JpcapCaptor
這個類是jPcap中的核心對象,一個JpcapCaptor對象表明了了系統中的一個網絡接口卡;經過對JpcapCaptor對象的調用,實現網絡數據包的抓取和發送。它供了一系列靜態方法調用如:獲取網卡列表,獲取某個網卡上的JpcapCaptor對象。
static NetworkInterface[]getDeviceList() 這個靜態方法調用,能夠返回機器上網絡接口卡對象的數組,數組中每個NetworkInterface元素對象表明一個網絡接口;通常使用jPcap所要作的第一步調用就是這個方法。
static JpcapCaptor openDevice(NetworkInterface interface, int snaplen, boolean promisc, int to_ms) 取得在指定網卡上的Jpcapcator對象,Interface:上所返回的某個網卡對象Snaplen:一次性要抓取數據包的最大長度。Promisc:設置是否混雜模式。處於混雜模式將接收全部數據包,若是設置爲混雜模式後調用了包過濾函數setFilter()將不起任何做用;To_ms:這個參數主要用於processPacket()方法,指定超時的時間;
 int loopPacket(int count, PacketReceiver handler) 經常使用的一種模式是,經過getDeviceListloopPacket方法中count參數表示要抓的包的數目,若是設備爲-1,責表示永遠抓下去---方法不會返回;第二個參數必須是實現了PacketReceiver接口的一個對象,抓到的包將調用這個PacketReceiver對象中的receivePacket(Packet packet)方法處理;因此抓包前,咱們必須寫一個實現了PacketReceiver接口的類。 特別注意的是:這個方法的調用會阻塞等待,若是沒有抓到指定count的包、或count設爲-1,這個方法都不會返回。因此,聰明的你確定想到了,若是要抓取機器上多個卡口上的包,這個方法必須放在一個獨立的線程中。()取得全部網絡接口,再經過openDevice方法取得每一個網絡接口上的JpcapCaptor對象,就可經過這個方法抓包了。
void breakLoop()       即上JpcapCaptor對象上阻塞等待的方法強制終止。當調用processPacket()和loopPacket()後,再調用這個方法能夠強制讓processPacket()和loopPacket()中止。
interface PacketReceiver :數據包處理器接口定義,要處理收到的數據包,必須編寫這個接口的實現類,在JpcapCaptor對象的loopPacket方法中調用. 這個接口中僅有一個方法定義:
Void receivePacket (Packet p)     實現類中處理接收到的Packet對象的方法。每一個Packet對象表明從熱指定網絡接口上抓取到的數據包。
NetworkInterface該類的每個實例表明一個網絡設備,通常就是網卡。這個類只有一些數據成員,除了繼承自java.lang.Object的基本方法之外,沒有定義其它方法。(但我還不知它與jdk5.0以上的API中的java.net.InterfaceAddress類是否能夠互換)。
NetworkInterfaceAddress[]addresses      這個接口的網絡地址。設定爲數組應該是考慮到有些設備同時鏈接多條線路,例如路由器。但咱們的PC機的網卡通常只有一條線路,因此咱們通常取addresses[0]就夠了。
java.lang.String datalink_description.     數據鏈路層的描述。描述所在的局域網是什麼網。例如,以太網(Ethernet)、無線LAN網(wireless LAN)、令牌環網(token ring)等等。
java.lang.String datalink_name datalink_name    該網絡設備所對應數據鏈路層的名稱。具體來講,例如Ethernet10M100M1000M等等。
java.lang.String description     網卡是XXXX牌子XXXX型號之類的描述。例如個人網卡描述:Realtek RTL8169/8110 Family Gigabit Ethernet NIC
boolean Loopback      標誌這個設備是否loopback設備。
byte[]mac_address     網卡的MAC地址,6個字節。
 java.lang.String Name     這個設備的名稱。例如個人網卡名稱:\Device\NPF_{3CE5FDA5-E15D-4F87-B217-255BCB351CD5}
 jPcap的 API使用很簡單,以下代碼示例:顯示機器上的全部網絡接口DispalyNetInterface.java:
Java代碼 複製代碼
  1. import jpcap.JpcapCaptor;   
  2. import jpcap.NetworkInterface;   
  3. import jpcap.PacketReceiver;   
  4. import jpcap.packet.Packet;   
  5. /**  
  6.  * 使用jpcap顯示網絡接口數據.  
  7.  * @author 胡東峯  
  8.  */  
  9. public class DispalyNetInterface {   
  10.        
  11.        
  12.    public static void main(String args[]){   
  13.        try{   
  14.  //獲取本機上的網絡接口對象數組   
  15.  final NetworkInterface[] devices = JpcapCaptor.getDeviceList();   
  16.         for(int i=0;i<devices.length;i++){   
  17.      NetworkInterface nc=devices[i];   
  18.      //一塊卡上可能有多個地址:   
  19.      String address="";   
  20.  for(int t=0;t<nc.addresses.length;t++){   
  21. address+="|addresses["+t+"]: "+nc.addresses[t].address.toString();   
  22.               }   
  23. //打印說明:   
  24.  System.out.println("第"+i+"個接口:"+"|name: "+nc.name   
  25. +"|loopback: "+nc.loopback+"\r\naddress: "+address);   
  26.         }   
  27.             
  28.         }catch(Exception ef){   
  29.             ef.printStackTrace();   
  30.      System.out.println("顯示網絡接口數據失敗:  "+ef);   
  31.     }   
  32.    }   
  33. }  
import jpcap.JpcapCaptor;
import jpcap.NetworkInterface;
import jpcap.PacketReceiver;
import jpcap.packet.Packet;
/**
 * 使用jpcap顯示網絡接口數據.
 * @author 胡東峯
 */
public class DispalyNetInterface {
	
	
   public static void main(String args[]){
	   try{
 //獲取本機上的網絡接口對象數組
 final NetworkInterface[] devices = JpcapCaptor.getDeviceList();
		for(int i=0;i<devices.length;i++){
	 NetworkInterface nc=devices[i];
	 //一塊卡上可能有多個地址:
	 String address="";
 for(int t=0;t<nc.addresses.length;t++){
address+="|addresses["+t+"]: "+nc.addresses[t].address.toString();
		      }
//打印說明:
 System.out.println("第"+i+"個接口:"+"|name: "+nc.name
+"|loopback: "+nc.loopback+"\r\naddress: "+address);
		}
		 
		}catch(Exception ef){
			ef.printStackTrace();
	 System.out.println("顯示網絡接口數據失敗:  "+ef);
	}
   }
} 
不幸的是,這段代碼運行時會報以下錯誤:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jpcap in java.library.path
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1682)    at java.lang.Runtime.loadLibrary0(Runtime.java:823)    at java.lang.System.loadLibrary(System.java:1030)    at jpcap.JpcapCaptor.<clinit>(JpcapCaptor.java:250)    at cn.netjava.cewolf.DispalyNetInterface.main(DispalyNetInterface.java:19) 
   還記得咱們介紹jPcap: 「它底層仍是使用了本機API經過Jini調用,在javaAPI中獲得數據」,這是由於當前cp中少了jpcap要調用的本地dll庫。將jpacp下載後lib下面的jpcap.dll複製到當前項目目錄下,若是你僅得制了jpcap.dll,操做系統沒有安裝wincap(http://www.winpcap.org/install/default.htm,則會看到以下錯誤提示: )
Exception in thread "main" java.lang.UnsatisfiedLinkError: E:\workspace\trafficManager\jpcap.dll: Can't find dependent libraries
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)    at java.lang.Runtime.loadLibrary0(Runtime.java:823)    at java.lang.System.loadLibrary(System.java:1030)    at jpcap.JpcapCaptor.<clinit>(JpcapCaptor.java:250)    at cn.netjava.cewolf.DispalyNetInterface.main(DispalyNetInterface.java:17)
配置無缺後,再次運行,輸出結果正常:
第0個接口:|name: \Device\NPF_GenericDialupAdapter|loopback: false
address: 第1個接口:|name: \Device\NPF_{2A5FD532-45A3-4A2B-9B68-F34C14E4FD2C}|loopback: falseaddress: |addresses[0]: /220.192.159.105第2個接口:|name: \Device\NPF_{14303C1A-4DB3-4BC9-979E-34063E070CBB}|loopback: falseaddress: |addresses[0]: /192.168.1.44
 在個人機器上,開着一塊局網網卡和一塊無線網卡,都顯示出來了;上面的 」第0個接口」就是指本機的127.0.0.1的迴環地址。但不知爲何,loopback也會是false?
 
 要注意兩點:一個是 jpcap.dll要在路徑中;另外,在統計流量時,本機迴環地址不須要統計,通常是第0個接口。接下來咱們看抓取網卡上的數據包是多麼簡單

博文出處:http://javafound.javaeye.com/blog/165704

html

相關文章
相關標籤/搜索