java网卡抓包

几年前做的,通过网卡抓包实现网站访问量,栏目,子栏目,文章点击量统计,记录备忘

主类

public class PortalNetSniffer
{
    public static String ModuleID = "PortalNetSniffer";
    public static void main(String[] args)
    {
            try
            {
                String host = "119.87.244.xxx;iread.com.cn";
                int port = 80;
            
                if(args.length > 0)
                {
                    ModuleID = args[0];
                    Mutex mutex = Mutex.read();
                    mutex.listen();
                }
            
                if(args.length > 1)
                {
                    host = args[1];
                }
                if(args.length > 2)
                {
                    //监听端口
                    String _port = args[2];
                    if(Tools.isNumeric(_port))
                    {
                    port = Integer.valueOf(_port);
                    }
                }
            
                //启动日志管理器
                Log.getInstance().setSubroot(ModuleID);
                Log.getInstance().setDebug(true);
                Log.getInstance().setLogable(true);
                Log.getInstance().start();
            
                final NetworkInterface devices[] = JpcapCaptor.getDeviceList();
                for(int i = 0; i < devices.length; i++)
                {
                    NetworkInterface ni = devices[i];
                    JpcapCaptor jpcap = JpcapCaptor.openDevice(ni, 2000, true, 20);
                    startCapThread(jpcap,host,port);
                    Log.msg("开始抓取第" + i + "个卡口上的数据");
                }
        }
        catch(Exception e)
        {
            Log.err("启动抓包线程失败:");
        }
    }

    private static void startCapThread(final JpcapCaptor jpcap,final String host,final int port)
    {
        Runnable runner = new Runnable()
        {
            public void run()
            {
                PortalPacketReceiver receiver = new PortalPacketReceiver(host,port);
                new Thread(receiver).start();
                jpcap.loopPacket(-1, receiver);
            }
        };
        new Thread(runner).start();
    }
}

主要干活的类

public class PortalPacketReceiver implements PacketReceiver,Runnable
{
	private String HOST = "119.87.xxx.xxx;iread.xxx.cn";
	private int PORT = 80;
	private List<?> validLinks = new ArrayList<String>();
	private _MemberClickDao _memberClickDao = null;

	private Queue<com.monitor.vo.Packet> data = new LinkedList<com.monitor.vo.Packet>();

	public PortalPacketReceiver(String host,int port)
	{
		this.HOST = host;
		this.PORT = port;
		File file = new File(ConfigUtil.getWorkPath(),"config");
		file = new File(file,"validLink");
		try
		{
			validLinks = FileUtils.readLines(file);
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	public void receivePacket(Packet packet)
	{
		//只处理TCP包
		if(packet instanceof jpcap.packet.TCPPacket)
		{
			TCPPacket p = (TCPPacket)packet;
			String s = "TCPPacket:| dst_ip " + p.dst_ip + ":" + p.dst_port + "|src_ip " + p.src_ip + ":" + p.src_port + " |len: " + p.len;
			//log.info(s);
			//只处理特定端口的包
			if(p.dst_port == PORT)
			{
				try
				{
					if(p.data != null && p.data.length > 0)
					{
						com.monitor.vo.Packet pk = new com.monitor.vo.Packet();
						pk.setSrcIp(p.src_ip.getHostAddress());
						pk.setSrcPort(p.src_port);
						pk.setDstPort(p.dst_port);
						pk.setData(new String(p.data));
						synchronized(this)
						{
							data.offer(pk);
							this.notify();
						}
					}
				}
				catch(Exception e)
				{
					Log.err("Error to handle packet");
				}
			}
		}
                //凌晨2点30,下班休息一分钟
		Calendar now = Calendar.getInstance(Locale.CHINA);
		int hour = now.get(Calendar.HOUR_OF_DAY);
		int minute = now.get(Calendar.MINUTE);
		if(hour == 2 && minute == 30)
		{
			ConnectionPool.disconnect();
			Log.getInstance().close();
			System.exit(0);
		}
	}

	public void run()
	{
		//启动数据库连接管理
        String serverHost = ConfigUtil.getString( "serverHost" );
        String dbType = ConfigUtil.getString( "dbType" );
        String dbName = ConfigUtil.getString( "dbName" );
        String dbDriver = ConfigUtil.getString( "dbDriver" );
        String dbUser = ConfigUtil.getString( "dbUser" );
        String dbPassword = ConfigUtil.getString( "dbPassword" );
        try
        {
        	ConnectionPool.connect(serverHost, dbType, dbName, dbDriver, dbUser, dbPassword );
        }
        catch(Exception e)
        {
        	System.exit(0);
        }
		while(true)
		{
			//Log.msg("Handle线程在运行");
			try
			{
				//log.info("list size = "+data.size());
				synchronized(this)
				{
					if(data.size() > 0)
					{
						//log.info("开始干活");
						com.monitor.vo.Packet pk = data.poll();
						Log.msg(pk.getData());
						if(pk != null)
						{
							analysis(pk);
						}
					}
					else
					{
						wait(1000);
					}
				}
			}
			catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
	}

	private synchronized void analysis(com.monitor.vo.Packet data)
	{
		try
		{
			List<Request> list = new ArrayList<Request>();
			String[] packet = data.getData().split("\\n\\s*\r",-1);
			for(int i = 0; i < packet.length; i++)
			{
				packet[i] = packet[i].trim();
				if(!packet[i].equals("") && (packet[i].startsWith("GET") || packet[i].startsWith("POST")))
				{
					Request req = new Request();
					req.setTime(new Date());
					req.setUserIp(data.getSrcIp());
					req.setSrcPort(data.getSrcPort());
					req.setDstPort(data.getDstPort());
					String[] lines = packet[i].split("\r\n");

					boolean isValidLink = false;
					for(int j = 0; j < lines.length; j++)
					{
						if(!lines[0].startsWith("GET") && !lines[0].startsWith("POST"))
						{
							break;
						}

						if(lines[j].startsWith("GET") || lines[i].startsWith("POST"))
						{
							String[] mup = lines[j].split(" ");
							if(mup.length > 0)
							{
								String method = mup[0].trim();
								req.setMethod(method);
							}
							if(mup.length > 1)
							{
								String uri = mup[1].trim();
								Log.msg("\r\nuri == " + uri);
								if(uri == null || "".equals(uri) || uri.endsWith("css") || uri.endsWith("js") || uri.endsWith("jpg") || uri.endsWith("png") || uri.endsWith("gif") || uri.endsWith("ico"))
								{
									break;
								}
								if(uri.equals("/"))break;

								for(int k = 0; k < validLinks.size(); k++)
								{
									if(uri.startsWith(validLinks.get(k).toString()))
									{
										isValidLink = true;
										break;
									}
								}
								if(!isValidLink)break;
								req.setUri(uri);
							}
							if(mup.length > 2)
							{
								String protocol = mup[2].trim();
								req.setProtocol(protocol);
							}
						}
						else
						{
							String[] arc = lines[j].split(":",2);
							if(arc.length > 1)
							{
								String key = arc[0].trim();
								String value = arc[1].trim();
								if(key.equalsIgnoreCase("Accept"))
								{
									req.setAccept(value);
								}
								else if(key.equalsIgnoreCase("Referer"))
								{
									req.setReferer(value);
								}
								else if(key.equalsIgnoreCase("Accept-Language"))
								{
									req.setAccept_language(value);
								}
								else if(key.equalsIgnoreCase("UA-CPU"))
								{
									req.setUa_cpu(value);
								}
								else if(key.equalsIgnoreCase("Accept-Encoding"))
								{
									req.setAccept_encoding(value);
								}
								else if(key.equalsIgnoreCase("If-Modified-Since"))
								{
									req.setIf_modified_since(value);
								}
								else if(key.equalsIgnoreCase("If-None-Match"))
								{
									req.setIf_none_match(value);
								}
								else if(key.equalsIgnoreCase("User-Agent"))
								{
									if(value != null)
									{
                                                                                //爬虫滚蛋
										if(value.indexOf("spider") != -1 || value.indexOf("Googlebot") != -1)
										{
											break;
										}
									}
									req.setUser_agent(value);
								}
								else if(key.equalsIgnoreCase("Host"))
								{
									if(value == null || "".equals(value) || HOST.indexOf(value) == -1)
									{
										break;
									}
									req.setHost(value);
								}
								else if(key.equalsIgnoreCase("Connection"))
								{
									req.setConnection(value);
								}
								else if(key.equalsIgnoreCase("Cookie"))
								{
									req.setCookie(value);
								}
								else if(key.equalsIgnoreCase("x-up-calling-line-id"))
								{
									if(value.startsWith("861") && value.length() ==13)
							    	{
										value = value.substring(2);
							    	}
									if(value.startsWith("+861") && value.length() == 14)
									{
										value = value.substring(3);
									}
									Log.msg("\r\nmobile ="+value);
									req.setMobile(value);
								}
							}
						}
					}
					if(req.getUri()!=null && !req.getUri().equals("") && !req.getUri().equals("/"))
					list.add(req);
				}
			}
                        
                        //下面进行分析,太长,略...
		}
		catch(Exception e)
		{
			Log.err("解析包异常:",e.getMessage());
		}
	}
}


你可能感兴趣的:(抓包,Jpcap,点击量)