zoukankan      html  css  js  c++  java
  • java 网络抓包



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





  • 相关阅读:
    Centos给php安装cassandra扩展
    树莓派配置文档 config.txt 说明(转)
    ubuntu远程桌面连接windows系统(转)
    Shell学习笔记
    linux终端terminal个性化配置(转)
    ubuntu14.04安装bodhi桌面系统后,unity启动界面改变,如何还原
    man curl_easy_perform(原创)
    man curl_easy_setopt(原创)
    树莓派 config.txt
    使用dd命令克隆整个系统(转)
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3130029.html
Copyright © 2011-2022 走看看