基于机器学习的网络流量识别分类(完整资源收米)NetFlow-Sentry

项目介绍

  • 这是一个名为NetFlow-Sentry的项目,项目实现了对网络流量的实时检测,特征抓取,内置了基于Pytorch的深度学习模型来进行流量分类。该项目除可以进行实时特征提取,还提供了网络流量数据的输入口,可以直接识别分类导入的网络流量文件。
  • 项目启动除要运行gradlew,还需要运行app.py脚本,脚本创建了一个Flask应用,用于沟通我们的模型和java项目。
  • 如有需要请私我
    声明:本项目为本人本科毕设成果
1.NetFlow-Sentry的目录框架:



各部分具体代码

FlowMgr类:

java 复制代码
package cic.cs.unb.ca.flow;

import cic.cs.unb.ca.Sys;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDate;


public class FlowMgr {

    protected static final Logger logger = LoggerFactory.getLogger(FlowMgr.class);

    public static final String FLOW_SUFFIX = "_Flow.csv";

    private static FlowMgr Instance = new FlowMgr();

    private String mFlowSavePath;
    private String mDataPath;

    private FlowMgr() {
        super();
    }
    
    public static FlowMgr getInstance() {
        return Instance;
    }

    public FlowMgr init() {

        String rootPath = System.getProperty("user.dir");
		StringBuilder sb = new StringBuilder(rootPath);
		sb.append(Sys.FILE_SEP).append("data").append(Sys.FILE_SEP);

		mDataPath = sb.toString();

        sb.append("daily").append(Sys.FILE_SEP);
        mFlowSavePath = sb.toString();

        return Instance;
    }

    public void destroy() {
    }

	public String getSavePath() {
		return mFlowSavePath;
	}

    public String getmDataPath() {
        return mDataPath;
    }

    public String getAutoSaveFile() {
		String filename = LocalDate.now().toString()+FLOW_SUFFIX;
		return mFlowSavePath+filename;
	}
}

ChartContainer.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.awt.*;

public class ChartContainer extends JPanel{
    protected static final Logger logger = LoggerFactory.getLogger(ChartContainer.class);

    private static Dimension maxDim;
    private static Dimension minDim;

    private static double zoomPercentage;

    private static Color boxDefaultColor;
    private static Color focusColor;

    Box parentBox;
    Box chartBox;

    ChartPanel chartPane;


    static{
        maxDim = new Dimension(ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH*4, ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT*4);
        minDim = new Dimension(ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH, ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT);
        zoomPercentage = 0.1;

        boxDefaultColor = Box.createHorizontalBox().getBackground();
        focusColor = UIManager.getColor("Tree.selectionBackground");

    }


    public ChartContainer(JFreeChart chart) {
        setLayout(new BorderLayout(0,0));

        chartPane = new ChartPanel(chart);

        chartPane.setMaximumSize(maxDim);
        chartPane.setMaximumDrawWidth(maxDim.width);
        chartPane.setMaximumDrawHeight(maxDim.height);
        chartPane.setMouseWheelEnabled(true);
        chartPane.setMouseZoomable(true);
        chartPane.setFillZoomRectangle(true);

        add(initChartBox(chartPane), BorderLayout.CENTER);
    }

    private Box initChartBox(ChartPanel chart) {

        parentBox = Box.createVerticalBox();

        chartBox = Box.createHorizontalBox();
        //Dimension d = new Dimension(500, 500);

        chartBox.setPreferredSize(minDim);
        chartBox.setMinimumSize(minDim);
        chartBox.setMaximumSize(minDim);

        //chartBox.add(Box.createHorizontalGlue());
        chartBox.add(chart);
        //chartBox.add(Box.createHorizontalGlue());


        parentBox.add(chartBox);
        parentBox.add(Box.createVerticalStrut(4));
        parentBox.add(new JSeparator(SwingConstants.HORIZONTAL));
        parentBox.add(Box.createVerticalStrut(4));

        return parentBox;
    }

    private JPanel init_btnPane(ChartPanel chart) {
        JPanel pane = new JPanel();

        pane.setLayout(new BoxLayout(pane,BoxLayout.Y_AXIS));


        JButton zoomIn = new JButton("Zoom In");
        JButton zoomOut = new JButton("Zoom Out");

        zoomIn.addActionListener(actionEvent -> {
            int w = getWidth();
            int h = getHeight();
            Dimension d = new Dimension(w + 10, h + 10);
            setPreferredSize(d);
            setMinimumSize(d);
            setMaximumSize(d);
            repaint();
            revalidate();
        });

        zoomOut.addActionListener(actionEvent -> chart.restoreAutoBounds());


        pane.add(Box.createVerticalGlue());
        pane.add(zoomIn);
        pane.add(Box.createVerticalGlue());
        pane.add(zoomOut);
        pane.add(Box.createVerticalGlue());

        return pane;
    }

    public void setFocus(boolean focus) {

        parentBox.setOpaque(true);
        if (focus) {
            parentBox.setBackground(focusColor);
        } else {
            parentBox.setBackground(boxDefaultColor);
        }

    }

    public void zoomIn() {

        Dimension d = chartBox.getSize();

        double w = d.width + d.width * zoomPercentage;
        double h = (w * d.height)/d.width;
        d.setSize(w, h);
        d = clipDim(d);

        chartBox.setPreferredSize(d);
        chartBox.setMinimumSize(d);
        chartBox.setMaximumSize(d);

        parentBox.setMaximumSize(d);

        chartBox.repaint();
        chartBox.revalidate();
    }

    public void zoomOut() {
        Dimension d = chartBox.getSize();

        double w = d.width - d.width * zoomPercentage;
        double h = (w * d.height)/d.width;
        d.setSize(w, h);

        chartBox.setPreferredSize(d);
        chartBox.setMinimumSize(d);
        chartBox.setMaximumSize(d);

        chartBox.repaint();
        chartBox.revalidate();
    }

    public void resetSize() {
        chartBox.setPreferredSize(minDim);
        chartBox.setMinimumSize(minDim);
        chartBox.setMaximumSize(minDim);
        chartBox.repaint();
        chartBox.revalidate();
    }

    public void resetScale() {
        chartPane.restoreAutoBounds();
    }

    private Dimension clipDim(Dimension dimension) {

        if (dimension == null) {
            return null;
        }

        if (dimension.width < minDim.width || dimension.height < minDim.height) {
            return minDim;
        } else if (dimension.width > maxDim.width || dimension.height > maxDim.height) {
            return maxDim;
        } else {
            return dimension;
        }
    }
}

FlowChartInfo.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

public class FlowChartInfo {

    private String name;

    private ChartContainer cc;


    public FlowChartInfo(String name, ChartContainer cc) {
        this.name = name;
        this.cc = cc;
    }

    public String getName() {
        return name;
    }

    public ChartContainer getCc() {
        return cc;
    }

    @Override
    public String toString() {
        return name;
    }
}

FlowChartPane.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

public class FlowChartPane extends JPanel{
    protected static final Logger logger = LoggerFactory.getLogger(FlowChartPane.class);

    private JPanel chartPane;
    private List<ChartContainer> ccList = new ArrayList<>();
    private ChartContainer focusCC = null;


    public FlowChartPane() {

        init();
        setLayout(new BorderLayout(0,0));
        setOpaque(true);
        JScrollPane jScrollPane = new JScrollPane(initBoxPane());
        jScrollPane.setPreferredSize(getPreferredSize());
        jScrollPane.setOpaque(true);

        add(jScrollPane, BorderLayout.CENTER);
    }

    private void init() {
    }

    private JPanel initBoxPane() {
        chartPane = new JPanel();

        chartPane.setLayout(new BoxLayout(chartPane,BoxLayout.Y_AXIS));
        chartPane.setOpaque(true);

        return chartPane;
    }

    public void addChartContainer(ChartContainer cc) {
        if (cc == null) {
            return;
        }

        cc.addMouseListener(mChartContainerMouseListener);

        ccList.add(cc);

        chartPane.add(cc);
        chartPane.repaint();
        chartPane.revalidate();
    }

    public void removeChart(){
        chartPane.removeAll();
        chartPane.revalidate();
        chartPane.repaint();
    }


    public void zoomIn() {
        if (focusCC != null) {
            focusCC.zoomIn();
        }
    }

    public void zoomOut() {
        if (focusCC != null) {
            focusCC.zoomOut();
        }
    }

    public void resetSize() {
        for (ChartContainer chartContainer : ccList) {
            chartContainer.resetSize();
        }
    }

    public void resetScale() {
        for (ChartContainer chartContainer : ccList) {
            chartContainer.resetScale();
        }
    }

    private MouseAdapter mChartContainerMouseListener = new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent mouseEvent) {
            super.mouseClicked(mouseEvent);
            ChartContainer cc = (ChartContainer) mouseEvent.getSource();
            for (ChartContainer chartContainer : ccList) {
                chartContainer.setFocus(false);
            }
            cc.setFocus(true);
            focusCC = cc;
        }
    };

}

FlowChartWorkerFactory.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

import cic.cs.unb.ca.jnetpcap.FlowFeature;
import cic.cs.unb.ca.weka.WekaFactory;
import cic.cs.unb.ca.weka.WekaXMeans;
import com.google.common.collect.Multimap;
import org.apache.commons.lang3.math.NumberUtils;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import weka.core.Attribute;
import weka.core.Instance;

import javax.swing.*;

public class FlowChartWorkerFactory {

    protected static final Logger logger = LoggerFactory.getLogger(FlowChartWorkerFactory.class);

    public static final int PIE_CHART = 1;
    public static final int BAR_CHART = 2;

    public static abstract class FlowChartSwingWorker<T, V> extends SwingWorker<T, V> {
        protected FlowFileInfo flowFileInfo;
        protected FlowFeature feature;
        protected int chartType;

        protected String title = "undefined";


        public FlowFileInfo getFlowFileInfo() {
            return flowFileInfo;
        }

        public FlowFeature getFeature() {
            return feature;
        }

        public int getChartType() {
            return chartType;
        }

        public String getChartTitle() {
            return title;
        }
    }

    public static class BuildProtocolChartWorker extends FlowChartSwingWorker<JFreeChart, String> {
        WekaXMeans xMeans;


        public BuildProtocolChartWorker(FlowFileInfo info, int type) {
            flowFileInfo = info;
            feature = FlowFeature.prot;
            chartType = type;
            xMeans = flowFileInfo.getxMeans();
        }

        @Override
        protected JFreeChart doInBackground() {

            if (xMeans ==null) {
                throw new IllegalArgumentException("xMeans should not be null");
            }
            JFreeChart chart;

            title = "Flows By " + feature.getName();

            Attribute attribute = WekaFactory.feature2attr(feature.getName(),feature.isNumeric());
            Multimap<String, Instance> protocol_multimap = xMeans.getMultiMap(attribute);
            switch(chartType){
                case PIE_CHART:
                    DefaultPieDataset pieDataset = new DefaultPieDataset();

                    for (String key : protocol_multimap.keySet()) {
                        pieDataset.setValue(FlowFeature.featureValue2String(feature,key),protocol_multimap.get(key).size());
                    }

                    chart = ChartFactory.createPieChart(
                            title,  // chart title
                            pieDataset,        // data
                            true,           // include legend
                            true,
                            false);

                    break;
                case BAR_CHART:

                    DefaultCategoryDataset barDataSet = new DefaultCategoryDataset();

                    for (String key : protocol_multimap.keySet()) {
                        barDataSet.setValue(protocol_multimap.get(key).size(),key,feature.getAbbr());
                    }


                    chart = ChartFactory.createBarChart(title,
                            "",
                            "num",
                            barDataSet, PlotOrientation.HORIZONTAL,
                            true,
                            true,
                            false);

                    break;
                default:
                    return null;
            }

            return chart;
        }

    }

    public static class BuildIPChartWorker extends FlowChartSwingWorker<JFreeChart, String> {

        WekaXMeans xMeans;

        public BuildIPChartWorker(FlowFileInfo info, FlowFeature f, int type) {
            flowFileInfo = info;
            feature = f;
            chartType = type;
            xMeans = flowFileInfo.getxMeans();
        }

        @Override
        protected JFreeChart doInBackground() {
            if (xMeans == null || feature ==null) {
                throw new IllegalArgumentException("xMeans or feature should not be null");
            }

            JFreeChart chart;
            title = "Flows By " + feature.getName();
            Attribute attribute = WekaFactory.feature2attr(feature.getName(),feature.isNumeric());
            Multimap<String, Instance> feature_value_map = xMeans.getMultiMap(attribute);

            switch(chartType){
                case PIE_CHART:
                    DefaultPieDataset pieDataset = new DefaultPieDataset();

                    for (String key : feature_value_map.keySet()) {
                        pieDataset.setValue(key,feature_value_map.get(key).size());
                    }

                    chart = ChartFactory.createPieChart(
                            title,  // chart title
                            pieDataset,        // data
                            true,           // include legend
                            true,
                            false);

                    break;
                case BAR_CHART:

                    DefaultCategoryDataset barDataSet = new DefaultCategoryDataset();

                    for (String key : feature_value_map.keySet()) {
                        double value = feature_value_map.get(key).size();
                        String rowKey = feature.getAbbr();
                        String colKey = key;
                        barDataSet.setValue(value,rowKey,colKey);
                    }

                    chart = ChartFactory.createBarChart(title,
                            null,
                            "Count",
                            barDataSet,
                            PlotOrientation.HORIZONTAL,
                            false,
                            true,
                            false);

                    break;
                default:
                    return null;
            }
            return chart;
        }

    }

    public static class BuildPortChartWorker extends FlowChartSwingWorker<JFreeChart, String> {
        WekaXMeans xMeans;

        public BuildPortChartWorker(FlowFileInfo info, FlowFeature f, int type) {
            flowFileInfo = info;
            feature = f;
            chartType = type;
            xMeans = flowFileInfo.getxMeans();
        }

        @Override
        protected JFreeChart doInBackground() {
            if (xMeans == null || feature ==null) {
                throw new IllegalArgumentException("xMeans or feature should not be null");
            }
            JFreeChart chart;
            title = "Flows By " + feature.getName();
            Attribute attribute = WekaFactory.feature2attr(feature.getName(),feature.isNumeric());
            Multimap<String, Instance> port_multimap = xMeans.getMultiMap(attribute);
            switch(chartType){
                case PIE_CHART:
                    DefaultPieDataset pieDataSet = new DefaultPieDataset();

                    for (String key : port_multimap.keySet()) {
                        Integer port = NumberUtils.createNumber(key).intValue();
                        pieDataSet.setValue(port,port_multimap.get(key).size());
                    }

                    chart = ChartFactory.createPieChart(
                            title,  // chart title
                            pieDataSet,        // data
                            true,           // include legend
                            true,
                            false);

                    break;
                case BAR_CHART:
                    DefaultCategoryDataset barDataSet = new DefaultCategoryDataset();

                    for (String key : port_multimap.keySet()) {
                        double value = port_multimap.get(key).size();
                        String rowKey = feature.getAbbr();
                        Integer colKey = NumberUtils.createNumber(key).intValue();
                        barDataSet.setValue(value,rowKey,colKey);
                    }

                    chart = ChartFactory.createBarChart(title,
                            "",
                            "Count",
                            barDataSet,PlotOrientation.HORIZONTAL,
                            false,
                            true,
                            false);

                    break;
                default:
                    return null;
            }
            return chart;
        }
    }
}

FlowFileInfo.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

import cic.cs.unb.ca.weka.WekaXMeans;

import java.io.File;

public class FlowFileInfo {

    private File filepath;
    private WekaXMeans xMeans;

    public FlowFileInfo(File filepath, WekaXMeans xMeans) {
        this.filepath = filepath;
        this.xMeans = xMeans;
    }


    @Override
    public String toString() {
        return filepath.getName();
    }

    public File getFilepath() {
        return filepath;
    }

    public WekaXMeans getxMeans() {
        return xMeans;
    }
}

FlowMonitorPane.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

import cic.cs.unb.ca.Sys;
import cic.cs.unb.ca.flow.FlowMgr;
import cic.cs.unb.ca.guava.Event.FlowVisualEvent;
import cic.cs.unb.ca.guava.GuavaMgr;
import cic.cs.unb.ca.jnetpcap.BasicFlow;
import cic.cs.unb.ca.jnetpcap.FlowFeature;
import cic.cs.unb.ca.jnetpcap.PcapIfWrapper;
import cic.cs.unb.ca.jnetpcap.worker.LoadPcapInterfaceWorker;
import cic.cs.unb.ca.jnetpcap.worker.TrafficFlowWorker;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.jnetpcap.PcapIf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cic.cs.unb.ca.jnetpcap.worker.InsertCsvRow;
import swing.common.InsertTableRow;
import swing.common.JTable2CSVWorker;
import swing.common.TextFileFilter;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.io.File;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FlowMonitorPane extends JPanel {
    protected static final Logger logger = LoggerFactory.getLogger(FlowMonitorPane.class);


    private JTable flowTable;
    private DefaultTableModel defaultTableModel;
    private JList<PcapIfWrapper> list;
    private DefaultListModel<PcapIfWrapper> listModel;
    private JLabel lblStatus;
    private JLabel lblFlowCnt;

    private TrafficFlowWorker mWorker;

    private JButton btnLoad;
    private JToggleButton btnStart;
    private JToggleButton btnStop;
    private ButtonGroup btnGroup;

    private JButton btnSave = new JButton();
    private File lastSave;
    private JButton btnGraph = new JButton();
    private JFileChooser fileChooser;

    private ExecutorService csvWriterThread;


    public FlowMonitorPane() {
        init();

        setLayout(new BorderLayout(5, 5));
        setBorder(new EmptyBorder(10, 10, 10, 10));

        add(initCenterPane(), BorderLayout.CENTER);
    }

    private void init() {
        csvWriterThread = Executors.newSingleThreadExecutor();
    }

    public void destory() {
        csvWriterThread.shutdown();
    }

    private JPanel initCenterPane(){
        JPanel pane = new JPanel();
        pane.setLayout(new BorderLayout(0, 0));
        pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));

        JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,initFlowPane(), initNWifsPane());
        splitPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));
        splitPane.setOneTouchExpandable(true);
        splitPane.setResizeWeight(1.0);

        pane.add(splitPane,BorderLayout.CENTER);
        return pane;
    }

    private JPanel initFlowPane() {
        JPanel pane = new JPanel();
        pane.setLayout(new BorderLayout(0, 5));
        pane.setBorder(BorderFactory.createLineBorder(new Color(0x555555)));

        //pane.add(initTableBtnPane(), BorderLayout.NORTH);
        pane.add(initTablePane(), BorderLayout.CENTER);
        pane.add(initStatusPane(), BorderLayout.SOUTH);

        return pane;
    }

    private JPanel initTablePane() {
        JPanel pane = new JPanel();
        pane.setLayout(new BorderLayout(0, 0));
        pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));


        String[] arrayHeader = StringUtils.split(FlowFeature.getHeader(), ",");
        defaultTableModel = new DefaultTableModel(arrayHeader,0);
        flowTable = new JTable(defaultTableModel);
        flowTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        JScrollPane scrollPane = new JScrollPane(flowTable);
        scrollPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));


        pane.add(scrollPane,BorderLayout.CENTER);

        return pane;
    }

    private JPanel initTableBtnPane(){
        JPanel btnPane = new JPanel();
        btnPane.setLayout(new BoxLayout(btnPane, BoxLayout.X_AXIS));
        btnSave = new JButton("Save as");
        btnGraph = new JButton("Graphs");
        btnSave.setFocusable(false);
        btnSave.setEnabled(false);
        btnGraph.setFocusable(false);
        btnGraph.setEnabled(false);

        fileChooser = new JFileChooser(new File(FlowMgr.getInstance().getmDataPath()));
        TextFileFilter csvChooserFilter = new TextFileFilter("csv file (*.csv)", new String[]{"csv"});
        fileChooser.setFileFilter(csvChooserFilter);

        btnSave.addActionListener(actionEvent -> {
            int action = fileChooser.showSaveDialog(FlowMonitorPane.this);
            if (action == JFileChooser.APPROVE_OPTION) {

                File selectedFile = fileChooser.getSelectedFile();
                String filename = selectedFile.getName();
                if (FilenameUtils.getExtension(filename).equalsIgnoreCase("csv")) {
                    //save name ok
                } else {
                    selectedFile = new File(selectedFile.getParentFile(), FilenameUtils.getBaseName(filename) + ".csv");
                }
                String title = "file conflict";
                String message = "Another file with the same name already exists,do you want to overwrite?";

                if (selectedFile.exists()) {

                    int reply = JOptionPane.showConfirmDialog(this, message, title, JOptionPane.YES_NO_OPTION);

                    if (reply == JOptionPane.YES_OPTION) {
                        JTable2CSVWorker worker = new JTable2CSVWorker(flowTable, selectedFile);
                        worker.execute();
                    } else {
                        btnSave.doClick();
                    }
                } else {
                    JTable2CSVWorker worker = new JTable2CSVWorker(flowTable, selectedFile);
                    worker.execute();
                }
                lastSave = selectedFile;
                btnGraph.setEnabled(true);
            }

        });

        btnGraph.addActionListener(actionEvent -> GuavaMgr.getInstance().getEventBus().post(new FlowVisualEvent(lastSave)));

        btnPane.add(Box.createHorizontalGlue());
        btnPane.add(btnSave);
        btnPane.add(Box.createHorizontalGlue());
        btnPane.add(btnGraph);
        btnPane.add(Box.createHorizontalGlue());

        btnPane.setBorder(BorderFactory.createRaisedSoftBevelBorder());

        return btnPane;
    }

    private JPanel initStatusPane() {
        JPanel pane = new JPanel();
        pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
        lblStatus = new JLabel("Get ready");
        lblStatus.setForeground(SystemColor.desktop);
        lblFlowCnt = new JLabel("0");

        pane.add(Box.createHorizontalStrut(5));
        pane.add(lblStatus);
        pane.add(Box.createHorizontalGlue());
        pane.add(lblFlowCnt);
        pane.add(Box.createHorizontalStrut(5));

        return pane;
    }

    private JPanel initNWifsPane() {
        JPanel pane = new JPanel(new BorderLayout(0, 0));
        pane.setBorder(BorderFactory.createLineBorder(new Color(0x555555)));
        pane.add(initNWifsButtonPane(), BorderLayout.WEST);
        pane.add(initNWifsListPane(), BorderLayout.CENTER);

        return pane;
    }

    private JPanel initNWifsButtonPane() {
        JPanel pane = new JPanel();
        pane.setBorder(BorderFactory.createEmptyBorder(10,15,10,15));
        pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));

        Dimension d = new Dimension(80,48);

        btnLoad = new JButton("Load");
        btnLoad.setMinimumSize(d);
        btnLoad.setMaximumSize(d);
        btnLoad.addActionListener(actionEvent -> loadPcapIfs());

        btnStart = new JToggleButton("Start");
        btnStart.setMinimumSize(d);
        btnStart.setMaximumSize(d);
        btnStart.setEnabled(false);
        btnStart.addActionListener(actionEvent -> startTrafficFlow());

        btnStop = new JToggleButton("Stop");
        btnStop.setMinimumSize(d);
        btnStop.setMaximumSize(d);
        btnStop.setEnabled(false);
        btnStop.addActionListener(actionEvent -> stopTrafficFlow());

        btnGroup = new ButtonGroup();
        btnGroup.add(btnStart);
        btnGroup.add(btnStop);

        pane.add(Box.createVerticalGlue());
        pane.add(btnLoad);
        pane.add(Box.createVerticalGlue());
        pane.add(btnStart);
        pane.add(Box.createVerticalGlue());
        pane.add(btnStop);
        pane.add(Box.createVerticalGlue());

        return pane;
    }

    private JPanel initNWifsListPane() {
        JPanel pane = new JPanel();
        pane.setLayout(new BorderLayout(0, 0));
        pane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));

        listModel = new DefaultListModel<>();
        listModel.addElement(new PcapIfWrapper("Click Load button to load network interfaces"));
        list = new JList<>(listModel);
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.setSelectedIndex(0);
        JScrollPane scrollPane = new JScrollPane(list);
        scrollPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0));

        pane.add(scrollPane,BorderLayout.CENTER);
        return pane;
    }

    private void loadPcapIfs() {
        LoadPcapInterfaceWorker task = new LoadPcapInterfaceWorker();
        task.addPropertyChangeListener(event -> {
            if ("state".equals(event.getPropertyName())) {
                LoadPcapInterfaceWorker task1 = (LoadPcapInterfaceWorker) event.getSource();
                switch (task1.getState()) {
                    case STARTED:
                        break;
                    case DONE:
                        try {
                            java.util.List<PcapIf> ifs = task1.get();
                            List<PcapIfWrapper> pcapiflist = PcapIfWrapper.fromPcapIf(ifs);

                            listModel.removeAllElements();
                            for(PcapIfWrapper pcapif :pcapiflist) {
                                listModel.addElement(pcapif);
                            }
                            btnStart.setEnabled(true);
                            btnGroup.clearSelection();

                            lblStatus.setText("pick one network interface to listening");
                            lblStatus.validate();

                        } catch (InterruptedException | ExecutionException e) {
                            logger.debug(e.getMessage());
                        }
                        break;
                }
            }
        });
        task.execute();
    }

    private void startTrafficFlow() {

        String ifName = list.getSelectedValue().name();

        if (mWorker != null && !mWorker.isCancelled()) {
            return;
        }

        mWorker = new TrafficFlowWorker(ifName);
        mWorker.addPropertyChangeListener(event -> {
            TrafficFlowWorker task = (TrafficFlowWorker) event.getSource();
            if("progress".equals(event.getPropertyName())){
                lblStatus.setText((String) event.getNewValue());
                lblStatus.validate();
            }else if (TrafficFlowWorker.PROPERTY_FLOW.equalsIgnoreCase(event.getPropertyName())) {
                insertFlow((BasicFlow) event.getNewValue());
            }else if ("state".equals(event.getPropertyName())) {
                switch (task.getState()) {
                    case STARTED:
                        break;
                    case DONE:
                        try {
                            lblStatus.setText(task.get());
                            lblStatus.validate();
                        } catch(CancellationException e){

                            lblStatus.setText("stop listening");
                            lblStatus.setForeground(SystemColor.GRAY);
                            lblStatus.validate();
                            logger.info("Pcap stop listening");

                        }catch (InterruptedException | ExecutionException e) {
                            logger.debug(e.getMessage());
                        }
                        break;
                }
            }
        });
        mWorker.execute();
        lblStatus.setForeground(SystemColor.desktop);
        btnLoad.setEnabled(false);
        btnStop.setEnabled(true);
    }

    private void stopTrafficFlow() {

        if (mWorker != null) {
            mWorker.cancel(true);
        }

        //FlowMgr.getInstance().stopFetchFlow();

        btnLoad.setEnabled(true);


        String path = FlowMgr.getInstance().getAutoSaveFile();
        logger.info("path:{}", path);

        if(defaultTableModel.getRowCount()>0 && new File(path).exists()) {
            StringBuilder msg = new StringBuilder("The flow has been saved to :");
            msg.append(Sys.LINE_SEP);
            msg.append(path);

            UIManager.put("OptionPane.minimumSize",new Dimension(0, 0));
            JOptionPane.showMessageDialog(this.getParent(),msg.toString());
        }
    }

    private void insertFlow(BasicFlow flow) {
        List<String> flowStringList = new ArrayList<>();
        List<String[]> flowDataList = new ArrayList<>();
        String flowDump = flow.dumpFlowBasedFeaturesEx();
        flowStringList.add(flowDump);
        flowDataList.add(StringUtils.split(flowDump, ","));

        //write flows to csv file
        String header  = FlowFeature.getHeader();
        String path = FlowMgr.getInstance().getSavePath();
        String filename = LocalDate.now().toString() + FlowMgr.FLOW_SUFFIX;
        csvWriterThread.execute(new InsertCsvRow(header, flowStringList, path, filename));

        //insert flows to JTable
        SwingUtilities.invokeLater(new InsertTableRow(defaultTableModel,flowDataList,lblFlowCnt));
        btnSave.setEnabled(true);
    }
}

FlowOfflinePane.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

import cic.cs.unb.ca.flow.FlowMgr;
import cic.cs.unb.ca.jnetpcap.BasicFlow;
import cic.cs.unb.ca.jnetpcap.FlowFeature;
import cic.cs.unb.ca.jnetpcap.worker.ReadPcapFileWorker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import cic.cs.unb.ca.jnetpcap.worker.InsertCsvRow;
import swing.common.PcapFileFilter;

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class FlowOfflinePane extends JPanel{
    protected static final Logger logger = LoggerFactory.getLogger(FlowOfflinePane.class);
    private static final Border PADDING = BorderFactory.createEmptyBorder(10,5,10,5);
    private JFileChooser fileChooser;
    private PcapFileFilter pcapChooserFilter;
    private JTextArea textArea;
    private JButton btnClr;
    private JComboBox<File> cmbInput;
    private JComboBox<File> cmbOutput;
    private Vector<File> cmbInputEle;
    private Vector<File> cmbOutputEle;

    private JComboBox<Long> param1;
    private JComboBox<Long> param2;
    private Vector<Long> param1Ele;
    private Vector<Long> param2Ele;

    private Box progressBox;
    private JProgressBar fileProgress;
    private JProgressBar fileCntProgress;

    private ExecutorService csvWriterThread;

    public FlowOfflinePane() {

        init();

        setLayout(new BorderLayout(5, 5));
        setBorder(new EmptyBorder(10, 10, 10, 10));

        add(initOutPane(), BorderLayout.CENTER);
        add(initCtrlPane(), BorderLayout.SOUTH);
    }

    private void init(){
        fileChooser = new JFileChooser(new File("."));
        pcapChooserFilter = new PcapFileFilter();
        fileChooser.setFileFilter(pcapChooserFilter);
        csvWriterThread = Executors.newSingleThreadExecutor();

    }

    public void destroy() {
        csvWriterThread.shutdown();
    }

    private JPanel initOutPane(){
        JPanel jPanel = new JPanel(new BorderLayout(5, 5));

        JScrollPane scrollPane = new JScrollPane();
        textArea = new JTextArea();
        textArea.setRows(36);
        textArea.setToolTipText("message");
        scrollPane.setViewportView(textArea);
        scrollPane.setBorder(BorderFactory.createLineBorder(new Color(0x555555)));

        /*JPanel msgSettingPane = new JPanel();
        msgSettingPane.setLayout(new BoxLayout(msgSettingPane, BoxLayout.X_AXIS));

        btnClr = new JButton("Clear");
        msgSettingPane.add(Box.createHorizontalGlue());
        msgSettingPane.add(btnClr);

        btnClr.addActionListener(actionEvent -> textArea.setText(""));*/

        jPanel.add(scrollPane, BorderLayout.CENTER);
        jPanel.add(initOutStatusPane(), BorderLayout.SOUTH);

        return jPanel;
    }

    private JPanel initOutStatusPane() {
        JPanel pane = new JPanel();
        pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));

        progressBox = Box.createVerticalBox();
        fileProgress = new JProgressBar();
        fileCntProgress = new JProgressBar();
        fileProgress.setBorderPainted(true);
        fileProgress.setStringPainted(true);
        fileCntProgress.setBorderPainted(true);
        fileCntProgress.setStringPainted(true);
        progressBox.add(fileProgress);
        progressBox.add(fileCntProgress);

        btnClr = new JButton("Clear");
        int height = fileProgress.getPreferredSize().height + fileCntProgress.getPreferredSize().height;
        Dimension d = new Dimension(80,height);
        btnClr.setPreferredSize(d);
        btnClr.setMaximumSize(d);
        btnClr.setMinimumSize(d);

        btnClr.addActionListener(actionEvent -> textArea.setText(""));

        progressBox.setVisible(false);

        pane.add(btnClr);
        pane.add(Box.createHorizontalStrut(18));
        pane.add(progressBox);

        return pane;
    }

    private JPanel initCtrlPane(){
        JPanel jPanel = new JPanel(new BorderLayout(5, 5));

        JPanel optPane = new JPanel();
        optPane.setLayout(new BoxLayout(optPane,BoxLayout.Y_AXIS));

        optPane.add(initFilePane());
        optPane.add(initSettingPane());
        optPane.add(initActionPane());

        jPanel.add(optPane, BorderLayout.CENTER);

        jPanel.setBorder(BorderFactory.createLineBorder(new Color(0x555555)));

        return jPanel;
    }

    private JPanel initFilePane(){
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new GridBagLayout());
        jPanel.setBorder(PADDING);
        GridBagConstraints gc = new GridBagConstraints();
        gc.insets = new Insets(10, 0, 10, 0);


        JLabel lblInputDir = new JLabel("Pcap dir:");
        JButton btnInputBrowse = new JButton("Browse");
        cmbInputEle = new Vector<>();
        cmbInput = new JComboBox<>(cmbInputEle);
        cmbInput.setEditable(true);
        btnInputBrowse.addActionListener(actionEvent -> {
            fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
            fileChooser.setFileFilter(pcapChooserFilter);
            int action = fileChooser.showOpenDialog(FlowOfflinePane.this);
            if (action == JFileChooser.APPROVE_OPTION) {
                File inputFile = fileChooser.getSelectedFile();
                logger.debug("offline select input {}", inputFile.getPath());
                setComboBox(cmbInput, cmbInputEle, inputFile);
            }
        });

        JLabel lblOutputDir = new JLabel("Output dir:");
        JButton btnOutputBrowse = new JButton("Browse");
        cmbOutputEle = new Vector<>();
        cmbOutput = new JComboBox<>(cmbOutputEle);
        cmbOutput.setEditable(true);
        btnOutputBrowse.addActionListener(actionEvent -> {
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            fileChooser.removeChoosableFileFilter(pcapChooserFilter);
            int action = fileChooser.showOpenDialog(FlowOfflinePane.this);
            if (action == JFileChooser.APPROVE_OPTION) {
                File outputFile = fileChooser.getSelectedFile();
                logger.debug("offline select output {}", outputFile.getPath());
                setComboBox(cmbOutput, cmbOutputEle, outputFile);
            }
        });

        //first row
        gc.gridx = 0;
        gc.gridy = 0;
        gc.weightx = 0;
        gc.weighty = 0.1;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        //gc.insets = new Insets(10, 5, 10, 5);
        jPanel.add(lblInputDir, gc);

        gc.gridx = 1;
        gc.gridy = 0;
        gc.weightx = 1;
        gc.weighty = 0.1;
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.anchor = GridBagConstraints.LINE_START;
        //gc.insets = new Insets(0, 10, 0, 0);
        gc.insets.left = gc.insets.right = 10;
        jPanel.add(cmbInput, gc);

        gc.gridx = 2;
        gc.gridy = 0;
        gc.weightx = 0;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        //gc.insets = new Insets(10, 5, 10, 0);
        jPanel.add(btnInputBrowse, gc);

        //second row
        gc.gridx = 0;
        gc.gridy = 1;
        gc.weightx = 0;
        gc.weighty = 0.1;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        //gc.insets = new Insets(10, 5, 10, 5);
        jPanel.add(lblOutputDir, gc);

        gc.gridx = 1;
        gc.gridy = 1;
        gc.weightx = 1;
        gc.fill = GridBagConstraints.HORIZONTAL;
        gc.anchor = GridBagConstraints.LINE_START;
        //gc.insets = new Insets(0, 10, 0, 0);
        gc.insets.left = gc.insets.right = 10;
        jPanel.add(cmbOutput, gc);

        gc.gridx = 2;
        gc.gridy = 1;
        gc.weightx = 0;
        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.LINE_END;
        //gc.insets = new Insets(10, 5, 10, 0);
        jPanel.add(btnOutputBrowse, gc);


        return jPanel;
    }

    private JPanel initSettingPane(){

        JPanel jPanel = new JPanel();
        jPanel.setLayout(new BoxLayout(jPanel,BoxLayout.X_AXIS));
        jPanel.setBorder(PADDING);

        JLabel lbl1 = new JLabel("Flow TimeOut:");
        param1Ele = new Vector<>();
        param1Ele.add(120000000L);
        param1 = new JComboBox<>(param1Ele);
        param1.setEditable(true);

        JLabel lbl2 = new JLabel("Activity Timeout:");
        param2Ele = new Vector<>();
        param2Ele.add(5000000L);
        param2 = new JComboBox<>(param2Ele);
        param2.setEditable(true);

        jPanel.add(lbl1);
        jPanel.add(param1);
        jPanel.add(Box.createHorizontalGlue());
        jPanel.add(lbl2);
        jPanel.add(param2);

        return jPanel;
    }

    private JPanel initActionPane() {
        JPanel jPanel = new JPanel();
        jPanel.setLayout(new BoxLayout(jPanel,BoxLayout.X_AXIS));
        jPanel.setBorder(PADDING);

        JButton btnOK = new JButton("OK");
        Dimension d = new Dimension(80,36);
        btnOK.setPreferredSize(d);
        btnOK.setMaximumSize(d);
        btnOK.setMinimumSize(d);
        jPanel.add(Box.createHorizontalGlue());
        jPanel.add(btnOK);
        jPanel.add(Box.createHorizontalGlue());
        btnOK.addActionListener(actionEvent -> startReadPcap());

        return jPanel;
    }

    private void setComboBox(JComboBox<File> combo, Vector<File> comboEle, File ele) {

        if (comboEle.contains(ele)) {
            combo.setSelectedItem(ele);
        } else {
            comboEle.addElement(ele);
            combo.setSelectedItem(comboEle.lastElement());
        }
    }

    private void updateOut(String str) {
        textArea.append(str);
        textArea.append(System.lineSeparator());
    }

    private long getComboParameter(JComboBox<Long> param,Vector<Long> paramEle) throws ClassCastException,NumberFormatException{
        long ret;
        int index = param.getSelectedIndex();
        String input;

        if (index < 0) {

            Object o = param.getEditor().getItem();
            if (o instanceof Long) {
                ret = (long) o;
            } else {
                input = (String) param.getEditor().getItem();
                ret = Long.valueOf(input);
            }
            paramEle.add(ret);

        } else {
            ret = paramEle.get(index);
        }
        return ret;
    }

    private void startReadPcap(){
        final File in;
        int cmbInIndex = cmbInput.getSelectedIndex();
        if (cmbInIndex < 0) {
            in = new File((String) cmbInput.getEditor().getItem());
        }else{
            in = cmbInputEle.get(cmbInIndex);
        }

        final File out;
        int cmbOutIndex = cmbOutput.getSelectedIndex();
        if (cmbOutIndex < 0) {
            out = new File((String) cmbOutput.getEditor().getItem());
        }else{
            out = cmbOutputEle.get(cmbOutIndex);
        }

        updateOut("You select: " + in.toString());
        updateOut("Out folder: " + out.toString());
        updateOut("-------------------------------");

        long flowTimeout;
        long activityTimeout;
        try {
            flowTimeout = getComboParameter(param1, param1Ele);
            activityTimeout = getComboParameter(param2, param2Ele);

            Map<String, Long> flowCnt = new HashMap<>();

            ReadPcapFileWorker worker = new ReadPcapFileWorker(in, out.getPath(), flowTimeout, activityTimeout);
            worker.addPropertyChangeListener(evt -> {
                ReadPcapFileWorker task = (ReadPcapFileWorker) evt.getSource();
                if ("progress".equals(evt.getPropertyName())) {
                    //logger.info("progress -> {}", evt.getNewValue());
                    List<String> chunks = (List<String>) evt.getNewValue();
                    if (chunks != null) {
                        SwingUtilities.invokeLater(() -> {
                            for (String str : chunks) {
                                updateOut(str);
                            }
                        });
                    }
                } else if ("state".equals(evt.getPropertyName())) {
                    switch (task.getState()) {
                        case STARTED:
                            progressBox.setVisible(true);
                            break;
                        case DONE:
                            progressBox.setVisible(false);
                            flowCnt.clear();
                            break;
                    }
                } else if (ReadPcapFileWorker.PROPERTY_FILE_CNT.equalsIgnoreCase(evt.getPropertyName())) {

                    int max = (int) evt.getOldValue();
                    int cur = (int) evt.getNewValue()+1;

                    fileCntProgress.setIndeterminate(false);
                    fileCntProgress.setMaximum(max);
                    fileCntProgress.setValue(cur);

                } else if (ReadPcapFileWorker.PROPERTY_CUR_FILE.equalsIgnoreCase(evt.getPropertyName())) {
                    fileProgress.setIndeterminate(true);
                    String curFile = (String) evt.getNewValue();
                    fileProgress.setString(curFile);
                    flowCnt.put(curFile, 0L);
                } else if (ReadPcapFileWorker.PROPERTY_FLOW.equalsIgnoreCase(evt.getPropertyName())) {

                    String fileName = (String) evt.getOldValue();
                    BasicFlow flow = (BasicFlow) evt.getNewValue();

                    flowCnt.put(fileName, flowCnt.get(fileName) + 1);

                    String msg = String.format("%d flows on Reading %s",flowCnt.get(fileName),fileName);
                    fileProgress.setString(msg);

                    //write flows to csv file
                    String header  = FlowFeature.getHeader();
                    csvWriterThread.execute(new InsertCsvRow(header, flow.dumpFlowBasedFeaturesEx(), out.getPath(), fileName+FlowMgr.FLOW_SUFFIX));
                }
            });
            worker.execute();
        } catch(ClassCastException | NumberFormatException e){
            logger.info("startRead: {}",e.getMessage());
            JOptionPane.showMessageDialog(FlowOfflinePane.this, "The parameter is not a number,please check and try again.", "Parameter error", JOptionPane.ERROR_MESSAGE);
        }
    }
}

FlowVisualPane.java类:

java 复制代码
package cic.cs.unb.ca.flow.ui;

import cic.cs.unb.ca.weka.WekaFactory;
import cic.cs.unb.ca.weka.WekaXMeans;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import swing.common.CsvPickerPane;
import swing.common.SwingUtils;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;
import java.beans.PropertyChangeEvent;
import java.io.File;
import java.util.concurrent.ExecutionException;

import static cic.cs.unb.ca.jnetpcap.FlowFeature.*;

/**
 * Created by yzhang29 on 03/01/18.
 */
public class FlowVisualPane extends JDesktopPane implements CsvPickerPane.CsvSelect{
    protected static final Logger logger = LoggerFactory.getLogger(FlowVisualPane.class);

    private CsvPickerPane pickerPane;
    private FlowChartPane flowChartPane;
    private JProgressBar progressBar;


    private JTree graphTree;
    private Multimap<FlowFileInfo,FlowChartInfo> treeNodeData;

    public FlowVisualPane() {

        init();

        setLayout(new BorderLayout(0, 3));
        //setBorder(Constants.LINEBORDER);

        pickerPane = new CsvPickerPane(this);
        pickerPane.setFilter("Flow");
        pickerPane.setSelectListener(this);

        flowChartPane = new FlowChartPane();

        add(pickerPane, BorderLayout.NORTH);
        add(flowChartPane,BorderLayout.CENTER);
        add(initOptionPane(), BorderLayout.WEST);
    }

    public FlowVisualPane(File file) {
        this();

        visualFile(file);

    }

    private void init() {
        progressBar = new JProgressBar();
        progressBar.setIndeterminate(true);

        treeNodeData = ArrayListMultimap.create();
    }

    public void visualFile(File file) {
        logger.info("visualFile {}",file.getPath());

        if (isFlowFileInfoExist(file)) {
            return;
        } else {
            flowChartPane.removeChart();
            final CreateXMeansWorker xMeansWorker = new CreateXMeansWorker(file);
            SwingUtils.setBorderLayoutPane(FlowVisualPane.this,progressBar,BorderLayout.SOUTH);
            xMeansWorker.execute();
        }
    }

    @Override
    public void onSelected(File file) {
        visualFile(file);
    }


    private JPanel initOptionPane() {
        JPanel pane = new JPanel(new BorderLayout());


        pane.add(initGraphTreePane(), BorderLayout.CENTER);
        pane.add(initGraphButtonPane(), BorderLayout.SOUTH);

        return pane;
    }


    private JScrollPane initGraphTreePane() {
        graphTree = new JTree(createTree());
        JScrollPane treeView = new JScrollPane(graphTree);

        return treeView;
    }

    private JPanel initGraphButtonPane() {
        JPanel pane = new JPanel();
        pane.setLayout(new BoxLayout(pane,BoxLayout.Y_AXIS));

        Box sizeBox = Box.createHorizontalBox();
        JLabel wlbl = new JLabel("Width: ");
        JSpinner widthSpinner;
        JSpinner heightSpinner;
        JLabel hlbl = new JLabel("Height: ");
        SpinnerNumberModel  widthSpinnerModel;
        SpinnerNumberModel  heightSpinnerModel;
        widthSpinnerModel = new SpinnerNumberModel(300,ChartPanel.DEFAULT_MINIMUM_DRAW_WIDTH,ChartPanel.DEFAULT_MAXIMUM_DRAW_WIDTH,12);
        heightSpinnerModel = new SpinnerNumberModel(200,ChartPanel.DEFAULT_MINIMUM_DRAW_HEIGHT,ChartPanel.DEFAULT_MAXIMUM_DRAW_HEIGHT,12);
        widthSpinner = new JSpinner(widthSpinnerModel);
        heightSpinner = new JSpinner(heightSpinnerModel);
        widthSpinner.setPreferredSize(heightSpinner.getPreferredSize());


        sizeBox.add(Box.createHorizontalStrut(16));
        sizeBox.add(wlbl);
        sizeBox.add(widthSpinner);
        sizeBox.add(Box.createHorizontalStrut(16));
        sizeBox.add(hlbl);
        sizeBox.add(heightSpinner);
        sizeBox.add(Box.createHorizontalStrut(16));
        sizeBox.setVisible(false);


        Dimension btnDim = new Dimension(116, 64);

        JButton zoomIn = new JButton("Zoom In");
        zoomIn.setPreferredSize(btnDim);
        zoomIn.addActionListener(actionEvent -> flowChartPane.zoomIn());

        JButton zoomOut = new JButton("Zoom Out");
        zoomOut.setPreferredSize(btnDim);
        zoomOut.addActionListener(actionEvent -> flowChartPane.zoomOut());


        JButton reset_size = new JButton("Reset size");
        reset_size.setPreferredSize(btnDim);
        reset_size.setMinimumSize(btnDim);
        reset_size.addActionListener(actionEvent -> flowChartPane.resetSize());

        JButton reset_scale = new JButton("Reset scale");
        reset_scale.setPreferredSize(btnDim);
        reset_scale.setMinimumSize(btnDim);
        reset_scale.addActionListener(actionEvent -> flowChartPane.resetScale());


        Box zoomBox = Box.createHorizontalBox();
        zoomBox.add(Box.createHorizontalStrut(16));
        zoomBox.add(zoomIn);
        zoomBox.add(Box.createHorizontalGlue());
        zoomBox.add(zoomOut);
        zoomBox.add(Box.createHorizontalStrut(16));


        Box resetBox = Box.createHorizontalBox();
        resetBox.add(Box.createHorizontalStrut(16));
        resetBox.add(reset_scale);
        resetBox.add(Box.createHorizontalGlue());
        resetBox.add(reset_size);
        resetBox.add(Box.createHorizontalStrut(16));

        pane.add(sizeBox);
        pane.add(Box.createVerticalStrut(24));
        pane.add(zoomBox);
        pane.add(Box.createVerticalStrut(24));
        pane.add(resetBox);
        pane.add(Box.createVerticalStrut(16));

        return pane;
    }

    private DefaultMutableTreeNode createTree() {
        DefaultMutableTreeNode top = new DefaultMutableTreeNode("Flow Chart");
//        DefaultMutableTreeNode branch1 = new DefaultMutableTreeNode("File Name");
//        DefaultMutableTreeNode graph1 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Protocol"));
//        DefaultMutableTreeNode graph2 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Src IP"));
//        DefaultMutableTreeNode graph3 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Dst IP"));
//        DefaultMutableTreeNode graph4 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Src Port"));
//        DefaultMutableTreeNode graph5 = new DefaultMutableTreeNode(new FlowChartInfo("Flows By Dst Port"));
//        branch1.add(graph1);
//        branch1.add(graph2);
//        branch1.add(graph3);
//        branch1.add(graph4);
//        branch1.add(graph5);


        //top.add(branch1);

        return top;
    }

    private void addChart2Tree(FlowFileInfo flowFileInfo, FlowChartInfo flowChartInfo) {
        DefaultTreeModel model = (DefaultTreeModel) graphTree.getModel();
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();

        DefaultMutableTreeNode fileInfoNode=null;
        for(int i=0;i<root.getChildCount();i++) {
            DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) root.getChildAt(i);

            FlowFileInfo fileInfoInNode = (FlowFileInfo) treeNode.getUserObject();

            if (fileInfoInNode == flowFileInfo) {
                logger.debug("tree node -> {} exist",flowFileInfo.getFilepath().getPath());
                fileInfoNode = treeNode;
                break;
            }
        }

        if (fileInfoNode == null) {
            fileInfoNode = new DefaultMutableTreeNode(flowFileInfo);
        }

        fileInfoNode.add(new DefaultMutableTreeNode(flowChartInfo));
        root.add(fileInfoNode);
        model.reload();

        treeNodeData.put(flowFileInfo, flowChartInfo);
    }

    private boolean isFlowFileInfoExist(File file) {

        if (file == null) {
            return false;
        }

        for (FlowFileInfo info : treeNodeData.keySet()) {
            if (info.getFilepath().getPath().equalsIgnoreCase(file.getPath())) {
                return true;
            }
        }
        return false;

    }

    private class CreateXMeansWorker extends SwingWorker<FlowFileInfo, String> {

        File csv;

        CreateXMeansWorker(File csv) {

            this.csv = csv;
        }

        @Override
        protected FlowFileInfo doInBackground() {

            if (csv == null) {
                throw new IllegalArgumentException("csv cannot be null");
            }


            WekaXMeans xMeans = new WekaXMeans(WekaFactory.loadFlowCsv(csv));

            FlowFileInfo flowFileInfo = new FlowFileInfo(csv, xMeans);

            return flowFileInfo;
        }

        @Override
        protected void done() {
            super.done();
            try {
                FlowFileInfo flowFileInfo = get();
                buildChart(flowFileInfo);
                SwingUtils.setBorderLayoutPane(FlowVisualPane.this,null,BorderLayout.SOUTH);
            } catch (InterruptedException | ExecutionException e) {
                logger.debug(e.getMessage());
            }
        }
    }

    public void buildChart(FlowFileInfo info) {
        logger.info("buildChart");

        FlowChartWorkerFactory.BuildProtocolChartWorker protocol_worker = new FlowChartWorkerFactory.BuildProtocolChartWorker(info,FlowChartWorkerFactory.PIE_CHART);
        protocol_worker.addPropertyChangeListener(event -> {
            //logger.info("build Protocol chart");
            ChartWorkerPropertyChange(event, protocol_worker);
        });
        protocol_worker.execute();

        FlowChartWorkerFactory.BuildIPChartWorker sip_worker = new FlowChartWorkerFactory.BuildIPChartWorker(info,src_ip,FlowChartWorkerFactory.BAR_CHART);
        sip_worker.addPropertyChangeListener(event -> {
            //logger.info("build src ip chart");
            ChartWorkerPropertyChange(event, sip_worker);
        });
        sip_worker.execute();

        FlowChartWorkerFactory.BuildIPChartWorker dip_worker = new FlowChartWorkerFactory.BuildIPChartWorker(info,dst_ip,FlowChartWorkerFactory.BAR_CHART);
        dip_worker.addPropertyChangeListener(event -> {
            //logger.info("build dst ip chart");
            ChartWorkerPropertyChange(event, dip_worker);
        });
        dip_worker.execute();

        FlowChartWorkerFactory.BuildPortChartWorker spt_worker = new FlowChartWorkerFactory.BuildPortChartWorker(info, src_port, FlowChartWorkerFactory.BAR_CHART);
        spt_worker.addPropertyChangeListener(event -> {
            //logger.info("build src port chart");
            ChartWorkerPropertyChange(event, spt_worker);
        });
        spt_worker.execute();

        FlowChartWorkerFactory.BuildPortChartWorker dpt_worker = new FlowChartWorkerFactory.BuildPortChartWorker(info, dst_pot, FlowChartWorkerFactory.BAR_CHART);
        dpt_worker.addPropertyChangeListener(event -> {
            //logger.info("build dst port chart");
            ChartWorkerPropertyChange(event, dpt_worker);
        });
        dpt_worker.execute();
    }

    private void ChartWorkerPropertyChange(PropertyChangeEvent event, FlowChartWorkerFactory.FlowChartSwingWorker<JFreeChart, String> task) {

        if ("state".equalsIgnoreCase(event.getPropertyName())) {

            SwingWorker.StateValue  sv = (SwingWorker.StateValue) event.getNewValue();

            switch (sv) {
                case STARTED:
                    SwingUtils.setBorderLayoutPane(FlowVisualPane.this,progressBar,BorderLayout.SOUTH);
                    break;
                case DONE:
                    try {
                        JFreeChart chart = task.get();


                        FlowFileInfo fileInfo = task.getFlowFileInfo();

                        ChartContainer cc = new ChartContainer(chart);

                        FlowChartInfo chartInfo = new FlowChartInfo(task.getChartTitle(),cc);

                        flowChartPane.addChartContainer(cc);
                        addChart2Tree(fileInfo, chartInfo);

                        SwingUtils.setBorderLayoutPane(FlowVisualPane.this,null,BorderLayout.SOUTH);
                    } catch (InterruptedException | ExecutionException e) {
                        logger.debug(e.getMessage());
                    }
                    break;
            }
        }
    }

}

FlowVisualEvent.java类:

java 复制代码
package cic.cs.unb.ca.guava.Event;

import java.io.File;

public class FlowVisualEvent {

    private File csv_file;

    public FlowVisualEvent(File csv_file) {
        this.csv_file = csv_file;
    }

    public File getCsv_file() {
        return csv_file;
    }
}

GuavaMgr.java类:

java 复制代码
package cic.cs.unb.ca.guava;

import com.google.common.eventbus.EventBus;

public class GuavaMgr {

    private static GuavaMgr Instance = new GuavaMgr();

    private EventBus mEventBus;


    public GuavaMgr() {
    }

    public static GuavaMgr getInstance() {
        return Instance;
    }

    public void init(){
        mEventBus = new EventBus("CICFlowMeter");
    }

    public EventBus getEventBus() {
        return mEventBus;
    }
}

FlowGenListener.java类:

java 复制代码
package cic.cs.unb.ca.jnetpcap.worker;

import cic.cs.unb.ca.jnetpcap.BasicFlow;

public interface FlowGenListener {
    void onFlowGenerated(BasicFlow flow);
}

InsertCsvRow.java类:

java 复制代码
package cic.cs.unb.ca.jnetpcap.worker;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static cic.cs.unb.ca.jnetpcap.Utils.FILE_SEP;
import static cic.cs.unb.ca.jnetpcap.Utils.LINE_SEP;

public class InsertCsvRow implements Runnable {
    public static final Logger logger = LoggerFactory.getLogger(InsertCsvRow.class);
    private String header;
    private List<String> rows;
    private String savepath = null;
    private String filename = null;

    public InsertCsvRow(String header, List<String> rows, String savepath, String filename) {
        this.header = header;
        this.rows = rows;
        this.savepath = savepath;
        this.filename = filename;
    }

    public InsertCsvRow(String header, String row, String savepath, String filename) {

        this.header = header;
        this.rows = new ArrayList<>();
        this.savepath = savepath;
        this.filename = filename;

        rows.add(row);
    }

    @Override
    public void run() {
        insert(header,rows,savepath,filename);
    }

    public static void insert(String header,List<String>  rows,String savepath, String filename) {
        if (savepath == null || filename == null || rows == null || rows.size() <= 0) {
            String ex = String.format("savepath=%s,filename=%s", savepath, filename);
            throw new IllegalArgumentException(ex);
        }

        File fileSavPath = new File(savepath);

        if(!fileSavPath.exists()) {
            fileSavPath.mkdirs();
        }


        if(!savepath.endsWith(FILE_SEP)){
            savepath += FILE_SEP;
        }

        File file = new File(savepath+filename);
        FileOutputStream output = null;

        try {
            if (file.exists()) {
                output = new FileOutputStream(file, true);
            }else{
                if (file.createNewFile()) {
                    output = new FileOutputStream(file);
                }
                if (header != null) {
                    output.write((header+LINE_SEP).getBytes());
                }
            }
            for (String row : rows) {
                output.write((row+LINE_SEP).getBytes());
            }

        } catch (IOException e) {
                logger.debug(e.getMessage());
        } finally {
            try {
                if (output != null) {
                    output.flush();
                    output.close();
                }
            } catch (IOException e) {
                logger.debug(e.getMessage());
            }
        }
    }
}

LoadPcapInterfaceWorker.java类:

java 复制代码
package cic.cs.unb.ca.jnetpcap.worker;

import java.util.ArrayList;
import java.util.List;

import javax.swing.SwingWorker;

import org.jnetpcap.Pcap;
import org.jnetpcap.PcapIf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class LoadPcapInterfaceWorker extends SwingWorker<List<PcapIf>,String>{

	public static final Logger logger = LoggerFactory.getLogger(LoadPcapInterfaceWorker.class);
	
	public LoadPcapInterfaceWorker() {
		super();
	}

	@Override
	protected List<PcapIf> doInBackground() throws Exception {
		
		StringBuilder errbuf = new StringBuilder();
		List<PcapIf> ifs = new ArrayList<>();
		if(Pcap.findAllDevs(ifs, errbuf)!=Pcap.OK) {
			logger.error("Error occured: " + errbuf.toString());
			throw new Exception(errbuf.toString());
		}
		return ifs;
	}

	@Override
	protected void done() {
		super.done();
	}
}

PcapReader.java类:

java 复制代码
package cic.cs.unb.ca.jnetpcap.worker;

import cic.cs.unb.ca.jnetpcap.*;
import org.jnetpcap.PcapClosedException;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import static cic.cs.unb.ca.jnetpcap.Utils.FILE_SEP;
import static cic.cs.unb.ca.jnetpcap.Utils.FLOW_SUFFIX;
import static cic.cs.unb.ca.jnetpcap.Utils.countLines;

public class PcapReader {


    public static void readFile(String inputFile, String outPath, long flowTimeout, long activityTimeout) {
        if(inputFile==null ||outPath==null ) {
            return;
        }

        //String fileName = FilenameUtils.getName(inputFile);
        Path p = Paths.get(inputFile);
        String fileName = p.getFileName().toString();

        if(!outPath.endsWith(FILE_SEP)){
            outPath += FILE_SEP;
        }

        File saveFileFullPath = new File(outPath+fileName+FLOW_SUFFIX);

        if (saveFileFullPath.exists()) {
            if (!saveFileFullPath.delete()) {
                System.out.println("Saved file full path cannot be deleted");
            }
        }

        FlowGenerator flowGen = new FlowGenerator(true, flowTimeout, activityTimeout);
        flowGen.addFlowListener(new FlowListener(fileName,outPath));
        boolean readIP6 = false;
        boolean readIP4 = true;
        PacketReader packetReader = new PacketReader(inputFile, readIP4, readIP6);

        System.out.println(String.format("Working on... %s",fileName));

        int nValid=0;
        int nTotal=0;
        int nDiscarded = 0;
        long start = System.currentTimeMillis();
        while(true) {
            try{
                BasicPacketInfo basicPacket = packetReader.nextPacket();
                nTotal++;
                if(basicPacket !=null){
                    flowGen.addPacket(basicPacket);
                    nValid++;
                }else{
                    nDiscarded++;
                }
            }catch(PcapClosedException e){
                break;
            }
        }

        flowGen.dumpLabeledCurrentFlow(saveFileFullPath.getPath(), FlowFeature.getHeader());

        long lines = countLines(saveFileFullPath.getPath());

        System.out.println(String.format("%s is done. total %d flows ",fileName,lines));
        System.out.println(String.format("Packet stats: Total=%d,Valid=%d,Discarded=%d",nTotal,nValid,nDiscarded));
        System.out.println("-----------------------------------------------------------------------------------------");

    }


    static class FlowListener implements FlowGenListener {

        private String fileName;

        private String outPath;

        private long cnt;

        public FlowListener(String fileName, String outPath) {
            this.fileName = fileName;
            this.outPath = outPath;
        }

        @Override
        public void onFlowGenerated(BasicFlow flow) {

            String flowDump = flow.dumpFlowBasedFeaturesEx();
            List<String> flowStringList = new ArrayList<>();
            flowStringList.add(flowDump);
            InsertCsvRow.insert(FlowFeature.getHeader(),flowStringList,outPath,fileName+ FLOW_SUFFIX);

            cnt++;

            String console = String.format("%s -> %d flows \r", fileName,cnt);

            System.out.print(console);
        }
    }
}

ReadPcapFileWorker.java类:

java 复制代码
package cic.cs.unb.ca.jnetpcap.worker;

import cic.cs.unb.ca.jnetpcap.*;
import org.jnetpcap.PcapClosedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import static cic.cs.unb.ca.jnetpcap.Utils.*;


public class ReadPcapFileWorker extends SwingWorker<List<String>,String> {

    public static final Logger logger = LoggerFactory.getLogger(ReadPcapFileWorker.class);
    public static final String PROPERTY_FILE_CNT = "file_count";
    public static final String PROPERTY_CUR_FILE = "file_current";
    public static final String PROPERTY_FLOW = "file_flow";
    private static final String DividingLine = "---------------------------------------------------------------------------------------------------------------";

    private long flowTimeout;
    private long activityTimeout;
    private int     totalFlows = 0;
    
    private File pcapPath;
    private String outPutDirectory;
    private List<String> chunks;

    public ReadPcapFileWorker(File inputFile, String outPutDir) {
        super();
        pcapPath = inputFile;
        outPutDirectory = outPutDir;
        chunks = new ArrayList<>();

        if(!outPutDirectory.endsWith(FILE_SEP)) {
            outPutDirectory = outPutDirectory + FILE_SEP;
        }
        flowTimeout = 120000000L;
        activityTimeout = 5000000L;
    }

    public ReadPcapFileWorker(File inputFile, String outPutDir,long param1,long param2) {
        super();
        pcapPath = inputFile;
        outPutDirectory = outPutDir;
        chunks = new ArrayList<>();

        if(!outPutDirectory.endsWith(FILE_SEP)) {
            outPutDirectory = outPutDirectory + FILE_SEP;
        }
        flowTimeout = param1;
        activityTimeout = param2;
    }

    @Override
    protected List<String> doInBackground() {

        if (pcapPath.isDirectory()) {
            readPcapDir(pcapPath,outPutDirectory);
        } else {

            if (!isPcapFile(pcapPath)) {
                publish("Please select pcap file!");
                publish("");
            } else {
                publish("CICFlowMeter received 1 pcap file");
                publish("");
                publish("");

                firePropertyChange(PROPERTY_CUR_FILE,"",pcapPath.getName());
                firePropertyChange(PROPERTY_FILE_CNT,1,1);//begin with 1
                readPcapFile(pcapPath.getPath(), outPutDirectory);
            }
        }
        /*chunks.clear();
        chunks.add("");
        chunks.add(DividingLine);
        chunks.add(String.format("TOTAL FLOWS GENERATED :%s", totalFlows));
        chunks.add(DividingLine);
        publish(chunks.toArray( new String[chunks.size()]));*/

        return chunks;
    }

    @Override
    protected void done() {
        super.done();
    }

    @Override
    protected void process(List<String> chunks) {
        super.process(chunks);
        firePropertyChange("progress","",chunks);
    }

    private void readPcapDir(File inputPath, String outPath) {
        if(inputPath==null||outPath==null) {
            return;
        }

        //File[] pcapFiles = inputPath.listFiles(file -> file.getName().toLowerCase().endsWith("pcap"));
        File[] pcapFiles = inputPath.listFiles(file -> isPcapFile(file));

        int file_cnt = pcapFiles.length;
        logger.debug("CICFlowMeter found :{} pcap files", file_cnt);
        publish(String.format("CICFlowMeter found :%s pcap files", file_cnt));
        publish("");
        publish("");

        for(int i=0;i<file_cnt;i++) {
            File file = pcapFiles[i];
            if (file.isDirectory()) {
                continue;
            }
            firePropertyChange(PROPERTY_CUR_FILE,"",file.getName());
            firePropertyChange(PROPERTY_FILE_CNT,file_cnt,i+1);//begin with 1
            readPcapFile(file.getPath(),outPath);
        }

    }

    private void readPcapFile(String inputFile, String outPath) {

        if(inputFile==null ||outPath==null ) {
            return;
        }

        Path p = Paths.get(inputFile);
        String fileName = p.getFileName().toString();//FilenameUtils.getName(inputFile);


        if(!outPath.endsWith(FILE_SEP)){
            outPath += FILE_SEP;
        }

        File saveFileFullPath = new File(outPath+fileName+Utils.FLOW_SUFFIX);

        if (saveFileFullPath.exists()) {
            if (!saveFileFullPath.delete()) {
                System.out.println("Saved file full path cannot be deleted");
            }
        }


        FlowGenerator flowGen = new FlowGenerator(true, flowTimeout, activityTimeout);
        flowGen.addFlowListener(new FlowListener(fileName));
        boolean readIP6 = false;
        boolean readIP4 = true;
        PacketReader packetReader = new PacketReader(inputFile, readIP4, readIP6);
        publish(String.format("Working on... %s",inputFile));
        logger.debug("Working on... {}",inputFile);

        int nValid=0;
        int nTotal=0;
        int nDiscarded = 0;
        long start = System.currentTimeMillis();
        while(true) {
            try{
                BasicPacketInfo basicPacket = packetReader.nextPacket();
                nTotal++;
                if(basicPacket !=null){
                    flowGen.addPacket(basicPacket);
                    nValid++;
                }else{
                    nDiscarded++;
                }
            }catch(PcapClosedException e){
                break;
            }
        }
        flowGen.dumpLabeledCurrentFlow(saveFileFullPath.getPath(), FlowFeature.getHeader());

        long lines = countLines(saveFileFullPath.getPath());

        long end = System.currentTimeMillis();

        chunks.clear();
        chunks.add(String.format("Done! Total %d flows",lines));
        chunks.add(String.format("Packets stats: Total=%d,Valid=%d,Discarded=%d",nTotal,nValid,nDiscarded));
        chunks.add(DividingLine);
        publish(chunks.toArray( new String[chunks.size()]));

        /*chunks.add(String.format("\t Total packets: %d",nTotal));
        chunks.add(String.format("\t Valid packets: %d",nValid));
        chunks.add(String.format("\t Ignored packets:%d %d ", nDiscarded,(nTotal-nValid)));
        chunks.add(String.format("PCAP duration %d seconds",((packetReader.getLastPacket()- packetReader.getFirstPacket())/1000)));
        chunks.add(DividingLine);
        int singleTotal = flowGen.dumpLabeledFlowBasedFeatures(outPath, fullname+ FlowMgr.FLOW_SUFFIX, FlowFeature.getHeader());
        chunks.add(String.format("Number of Flows: %d",singleTotal));
        chunks.add("");
        publish(chunks.toArray( new String[chunks.size()]));
        totalFlows += singleTotal;

        logger.debug("{} is done,Total {}",inputFile,singleTotal);*/
    }


    class FlowListener implements FlowGenListener {

        private String fileName;

        FlowListener(String fileName) {
            this.fileName = fileName;
        }

        @Override
        public void onFlowGenerated(BasicFlow flow) {
            firePropertyChange(PROPERTY_FLOW,fileName,flow);
        }
    }

}

TrafficFlowWorker.java类:

java 复制代码
package cic.cs.unb.ca.jnetpcap.worker;

import cic.cs.unb.ca.jnetpcap.BasicFlow;
import cic.cs.unb.ca.jnetpcap.FlowGenerator;
import cic.cs.unb.ca.jnetpcap.PacketReader;
import org.jnetpcap.Pcap;
import org.jnetpcap.nio.JMemory.Type;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.util.List;

public class TrafficFlowWorker extends SwingWorker<String,String> implements FlowGenListener{

	public static final Logger logger = LoggerFactory.getLogger(TrafficFlowWorker.class);
    public static final String PROPERTY_FLOW = "flow";
	private String device;


    public TrafficFlowWorker(String device) {
		super();
		this.device = device;
	}

	@Override
	protected String doInBackground() {
		
		FlowGenerator   flowGen = new FlowGenerator(true,120000000L, 5000000L);
		flowGen.addFlowListener(this);
		int snaplen = 64 * 1024;//2048; // Truncate packet at this size
		int promiscous = Pcap.MODE_PROMISCUOUS;
		int timeout = 60 * 1000; // In milliseconds
		StringBuilder errbuf = new StringBuilder();
		Pcap pcap = Pcap.openLive(device, snaplen, promiscous, timeout, errbuf);
		if (pcap == null) {
			logger.info("open {} fail -> {}",device,errbuf.toString());
			return String.format("open %s fail ->",device)+errbuf.toString();
		}

		PcapPacketHandler<String> jpacketHandler = (packet, user) -> {

            /*
             * BufferUnderflowException while decoding header
             * that is because:
             * 1.PCAP library is not multi-threaded
             * 2.jNetPcap library is not multi-threaded
             * 3.Care must be taken how packets or the data they referenced is used in multi-threaded environment
             *
             * typical rule:
             * make new packet objects and perform deep copies of the data in PCAP buffers they point to
             *
             * but it seems not work
             */

            PcapPacket permanent = new PcapPacket(Type.POINTER);
            packet.transferStateAndDataTo(permanent);

            flowGen.addPacket(PacketReader.getBasicPacketInfo(permanent, true, false));
            if(isCancelled()) {
                pcap.breakloop();
                logger.debug("break Packet loop");
            }
        };

        //FlowMgr.getInstance().setListenFlag(true);
        logger.info("Pcap is listening...");
        firePropertyChange("progress","open successfully","listening: "+device);
        int ret = pcap.loop(Pcap.DISPATCH_BUFFER_FULL, jpacketHandler, device);

		String str;
        switch (ret) {
            case 0:
                str = "listening: " + device + " finished";
                break;
            case -1:
                str = "listening: " + device + " error";
                break;
            case -2:
                str = "stop listening: " + device;
                break;
                default:
                    str = String.valueOf(ret);
        }

        return str;
	}

	@Override
	protected void process(List<String> chunks) {
		super.process(chunks);
	}

	@Override
	protected void done() {
		super.done();
	}

	@Override
	public void onFlowGenerated(BasicFlow flow) {
        firePropertyChange(PROPERTY_FLOW,null,flow);
	}
}
相关推荐
肥猪猪爸9 分钟前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet
色空大师12 分钟前
23种设计模式
java·开发语言·设计模式
闲人一枚(学习中)12 分钟前
设计模式-创建型-建造者模式
java·设计模式·建造者模式
vortex512 分钟前
信息收集系列(六):路径爬取与目录爆破
网络安全·渗透·信息收集
2202_7544215430 分钟前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
蓝染-惣右介32 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
小林想被监督学习33 分钟前
idea怎么打开两个窗口,运行两个项目
java·ide·intellij-idea
HoneyMoose35 分钟前
IDEA 2024.3 版本更新主要功能介绍
java·ide·intellij-idea
我只会发热37 分钟前
Java SE 与 Java EE:基础与进阶的探索之旅
java·开发语言·java-ee
LZXCyrus38 分钟前
【杂记】vLLM如何指定GPU单卡/多卡离线推理
人工智能·经验分享·python·深度学习·语言模型·llm·vllm