网络抓包工具的首选是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 大神的项目包也传上去了。以后备用。