网络抓包工具的首选是Sniffer。但分析数据时有局限性。比如我要同时监听所有的网卡。筛选发送到某个地址的数据生成绘图等等。
参考了 http://javafound.iteye.com/blog/165723 ,javafound 大神基于jpcap的网络实时监控程序。我想做数据分析,就在程序上改了一下去除了图形生成,改成了数据入库以便对数据进行分析。
主类:Tcpdump.java
package com.fitweber.socket; import java.util.Map; import jpcap.JpcapCaptor; import jpcap.NetworkInterface; /** * 1.使用jpcap抓取网络流量的主类, * 2.这个类要根据网卡个数,启动线程分别抓取各个网卡上的流量入表中 * 3.生成图表的对象从流量表中取出数据 * 4.这个类设计为单实例,在第一次调用时启动抓数据线程; * 5.目前没有设计停止抓取机制.... * @author www.NetJava.cn modify by wheatmark */ public class Tcpdump { private Tcpdump(){} /**存入某个地址名字和流量统计值*/ private Map<String, Integer> nameTrafficMap=new java.util.HashMap(); //单实例 private static Tcpdump tcpdump=null; public static void main(String args[]){ //启动统计线程 Tcpdump.ins(); } /** * 单实例调用:其它对象调用这个类的方法时,必须通过这个方法 * 这样,保证了流量统计线程的启动,且只启动了一次 * */ public synchronized static Tcpdump ins(){ if(null==tcpdump){ tcpdump=new Tcpdump(); tcpdump.init(); } return tcpdump; } /**生成报表的Servlet调用用于生成图表中数据*/ public Map<String, Integer> getNameTrafficMap(){ return nameTrafficMap; } /** * 根据网卡个数,启动统计线程 * 注意:本地地址,即127.0.0.1上的不统计 */ private void init() { try{ //获取本机上的网络接口对象 final NetworkInterface[] devices = JpcapCaptor.getDeviceList(); /* * /172.16.175.242 */ for(int i=0;i<devices.length;i++){ NetworkInterface nc=devices[i]; //大与零则为有效网卡,不抓本机地址. if(nc.addresses.length>0){ //一个网卡可能有多个地址,只取第一个地址 String addr=nc.addresses[0].address.toString(); // 创建某个卡口上的抓取对象, JpcapCaptor jpcap = JpcapCaptor.openDevice(nc, 2000, true, 100); //创建对应的抓取线程并启动 LoopPacketThread lt=new LoopPacketThread(jpcap,addr,nc); lt.start(); System.out.println( addr+"上的采集线程己启动************"); } } }catch(Exception ef){ ef.printStackTrace(); System.out.println("start caputerThread error ! ! ! !"+ef); } } /**IP和抓到包的长度放入hash表中,用表中长度加入放入的长度*/ /** void putNetValue(String name,int value){ if(nameTrafficMap.containsKey(name)){ value=nameTrafficMap.get(name)+value; nameTrafficMap.put(name, value); }else{ nameTrafficMap.put(name, value); } } **/ } // /**测试再加上一个内存监视线程*/ //class CheckMemory extends Thread{ // // public void run(){ // while(true){ // try{ // //计算内存占用量 // long freeM= java.lang.Runtime.getRuntime().freeMemory(); // Long result=java.lang.Runtime.getRuntime().totalMemory()-freeM; // String rs=""+result/1000; // int is=Integer.parseInt(rs); // // Tcpdump.ins().putNetValue("这是内存占用", is); // // Thread.sleep(1000); // }catch(Exception ef){ // // } // } // } // //}
数据抓取:DumpPacket.java
package com.fitweber.socket; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.Date; import jpcap.NetworkInterface; import jpcap.PacketReceiver; import jpcap.packet.ARPPacket; import jpcap.packet.EthernetPacket; import jpcap.packet.IPPacket; import jpcap.packet.Packet; import jpcap.packet.TCPPacket; import jpcap.packet.UDPPacket; import com.fitweber.pojo.WebPacket; import com.fitweber.util.DataLoger; /** * 抓包监听器,实现PacketReceiver中的方法,当数据包到达时计数. * @author www.NetJava.cn */ class DumpPacket implements PacketReceiver { private String ipAdd; private DataLoger dataLoger; private NetworkInterface nc; private String addresses; DumpPacket(String ipAdd,NetworkInterface nc){ this.ipAdd=ipAdd; this.nc = nc; this.addresses = nc.addresses[0].address.toString(); this.dataLoger = new DataLoger(); } //实现包统计 public void receivePacket(Packet packet) { WebPacket webPacket = new WebPacket(); webPacket.setAddresses(this.addresses);//监听网卡地址 EthernetPacket ethernetPacket = (EthernetPacket) packet.datalink; webPacket.setSource_mac(ethernetPacket.getSourceAddress());//请求硬件地址 webPacket.setDest_mac(ethernetPacket.getDestinationAddress());//目标硬件地址 if("class jpcap.packet.ARPPacket".equals(packet.getClass().toString())){ ARPPacket arppacket = (ARPPacket) packet; webPacket.setCaplen(arppacket.len);//网络包长度 webPacket.setHeader_data(arppacket.header);//报文头部信息 webPacket.setPacket_data(arppacket.data);//报文数据 webPacket.setReceive_date(new Timestamp(arppacket.sec*1000+arppacket.usec/1000));//收报时间 }else{ IPPacket ippacket = (IPPacket) packet; webPacket.setSource_ip(ippacket.src_ip.getHostAddress());//请求IP地址 webPacket.setDest_ip(ippacket.dst_ip.getHostAddress());//目标IP地址 webPacket.setProtocol(ippacket.protocol);//网络协议 webPacket.setPriority(ippacket.priority);//优先级 webPacket.setVersion(ippacket.version);//版本 webPacket.setHop_limit(ippacket.hop_limit);//生存时间 webPacket.setIdent(ippacket.ident);//分组标识 webPacket.setCaplen(ippacket.len);//网络包长度 webPacket.setDatalen(ippacket.length);//数据包长度 webPacket.setHeader_data(ippacket.header);//报文头部信息 webPacket.setPacket_data(ippacket.data);//报文数据 webPacket.setReceive_date(new Timestamp(ippacket.sec*1000+ippacket.usec/1000));//收报时间 //System.out.println("服务类型(TOS) (v4/v6):"+ippacket.rsv_tos); //System.out.println(ippacket); if(ippacket.protocol == 6){ TCPPacket tcppacket =(TCPPacket) ippacket; webPacket.setSrc_port(tcppacket.src_port);//源端口 webPacket.setDst_port(tcppacket.dst_port);//目标端口 } if(ippacket.protocol == 17){ UDPPacket udppacket =(UDPPacket) ippacket; webPacket.setSrc_port(udppacket.src_port);//源端口 webPacket.setDst_port(udppacket.dst_port);//目标端口 } } this.dataLoger.saveLog(webPacket); } /** *日志时间信息 * @return:日志内容时间 */ private static String currentTime(){ Date d = new Date(); SimpleDateFormat kk=new SimpleDateFormat("mm:ss"); String strTime=kk.format(d); return strTime; } }
数据入库:DataLoger.java
package com.fitweber.util; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import com.fitweber.dao.WebPacketDao; import com.fitweber.pojo.WebPacket; public class DataLoger { final private int LOGTIME = 50; private ArrayList<WebPacket> webPacketArray = new ArrayList<WebPacket>(); private WebPacketDao webPacketDao; public DataLoger(){ String resource = "META-INF/conf/mybatis-config.xml"; InputStream inputStream; try { inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); this.webPacketDao = session.getMapper(WebPacketDao.class); } catch (IOException e) { e.printStackTrace(); } } public void saveLog(WebPacket webPacket) { if(webPacketArray.size()<LOGTIME){ webPacketArray.add(webPacket); }else{ //保存数据 webPacketDao.insertWebPacket(webPacketArray); webPacketArray.clear(); webPacketArray.add(webPacket); } } }
这里汇总一下java 网络监听的知识点。把相关的资料传到 http://download.csdn.net/detail/super2007/5553057 。javafound 大神的项目包也传上去了。以后备用。