基于机器学习的网络流量识别分类

news2024/12/30 3:16:12

1.cicflowmeter的目录框架:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

各部分具体代码

FlowMgr类:

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类:

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类:

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类:

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类:

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类:

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类:

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类:

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类:

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类:

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类:

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类:

package cic.cs.unb.ca.jnetpcap.worker;

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

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

InsertCsvRow.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类:

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类:

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类:

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类:

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);
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1643379.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

每日一博 - 闲聊架构设计中的多级缓存设计

文章目录 方法论概述客户端缓存应用层缓存服务层缓存缓存设计的注意事项总结 思维导图戳这里 方法论概述 从客户端到服务层&#xff0c;缓存的应用广泛而重要。通过合理的缓存设计&#xff0c;能够有效地提高系统的性能并降低延迟。 客户端缓存 在客户端层面&#xff0c;浏览…

代码学习录打卡Day13

1 滑动窗口最大值 使用单调队列&#xff0c;需要一个队列&#xff0c;这个队列呢&#xff0c;放进去窗口里的元素&#xff0c;然后随着窗口的移动&#xff0c;队列也一进一出&#xff0c;每次移动之后&#xff0c;队列告诉我们里面的最大值是什么。 class MyQueue { public:vo…

JavaEE 多线程详细讲解(1)

1.线程是什么 &#xff08;shift F6&#xff09;改类名 1.1.并发编程是什么 &#xff08;1&#xff09;当前的CPU&#xff0c;都是多核心CPU &#xff08;2&#xff09;需要一些特定的编程技巧&#xff0c;把要完成的仍无&#xff0c;拆解成多个部分&#xff0c;并且分别让…

Python-VBA函数之旅-open函数

目录 一、open函数的常见应用场景 二、open函数使用注意事项 三、如何用好open函数&#xff1f; 1、open函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;神奇夜光杯-CSDN博客 一、open函数的常见应用场…

【平时工作中的各种术语__持续更新~~~~】

中文&#xff1a; 1、jar包 JAR包&#xff08;Java Archive Package&#xff09;是一种将多个Java类文件以及与它们相关的元数据和资源&#xff08;如文本、图片等&#xff09;打包到一个单一文件中的归档工具。它基于ZIP文件格式。JAR文件主要用于分发和部署Java应用程序。J…

GitHub Desktop安装与使用教程

GitHub Desktop 是GitHub公司推出的一款桌面应用程序&#xff0c;旨在帮助开发人员更轻松使用GitHub。它提供了一个直观的用户界面&#xff0c;允许用户通过图形化界面来执行常见的 Git 操作&#xff0c;如克隆仓库、创建分支、提交更改、合并代码等。 GitHub Desktop 的设计使…

数仓开发:DIM层数据处理

一、了解DIM层 这个就是数仓开发的分层架构 我们现在是在DIM层&#xff0c;从ods表中数据进行加工处理&#xff0c;导入到dwd层&#xff0c;但是记住我们依然是在DIM层&#xff0c;而非是上面的ODS和DWD层。 二、处理维度表数据 ①先确认hive的配置 -- 开启动态分区方案 -- …

AI智体的分级:从基于规则到基于LLM

摘要&#xff1a; AI智体被定义为感知环境、做出决策和采取行动的人工实体。受SAE&#xff08;汽车工程师学会&#xff09;自动驾驶6个级别的启发&#xff0c;AI智体也根据效用和强度进行分类&#xff0c;分为以下几个级别&#xff1a;L0——无AI&#xff0c;有工具&#xff0…

proc 文件系统

proc 文件系统是一个虚拟文件系统&#xff0c;它以文件系统的方式为应用层访问系统内核数据提供了接口 &#xff0c; 用户和应用程序可以通过 proc 文件系统得到系统信息和进程相关信息 &#xff0c;对 proc 文件系统的读写作为与内核进行通信的一种手段。但是与普通文件不同的…

Flutter笔记:Widgets Easier组件库(12)使用消息吐丝(Notify Toasts)

Flutter笔记 Widgets Easier组件库&#xff08;12&#xff09;使用消息吐丝&#xff08;Notify Toasts&#xff09; - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 29114848416…

【软考高项】三十二、成本管理域计算题相关概念和公式

一、相关缩写表示 BACBudget at Completion----完工预算 ACActual Cost----实际成本 EVEarned Value----挣值 PVPlanned Value----计划价值 CVCost Variance----成本偏差 SVSchedule Variance----进度偏差 CPICost Performance Index----成本绩效指数 SPI Schedule Performanc…

RSA加密---java和node兼容版(可直接复制使用)

目录 背景 实现 一、node代码 1、引入依赖 2、生成公钥和私钥 3、生成工具类 二、java代码 背景 本来项目的后端是node&#xff0c;里面登录接口用的是后端生成RSA公钥和私钥&#xff0c;公钥给前端网页用来加密&#xff0c;node后端解密&#xff0c;一切很和谐&#x…

带环链表和链表的复制,检验你链表的学习情况

前言&#xff1a;带环链表是链表中的经典问题&#xff0c;需要一定的数理思维&#xff0c;一定要掌握其来龙去脉&#xff0c;这样可以加深理解。本文主要讲解一下个人对带环链表的理解。 带环链关的OJ题 1.判断链表是否带环 题目&#xff1a; 141. 环形链表 给你一个链表的头…

深入理解网络原理2----UDP协议

文章目录 前言一、UDP协议协议段格式&#xff08;简图&#xff09;校验和 二、UDP与TCP 前言 随着时代的发展&#xff0c;越来越需要计算机之间互相通信&#xff0c;共享软件和数据&#xff0c;即以多个计算机协同⼯作来完成业务&#xff0c;就有了⽹络互连。 一、UDP协议 协…

GRU模块:nn.GRU层的输出state与output

在 GRU&#xff08;Gated Recurrent Unit&#xff09;中&#xff0c;output 和 state 都是由 GRU 层的循环计算产生的&#xff0c;它们之间有直接的关系。state 实际上是 output 中最后一个时间步的隐藏状态。 GRU 的基本公式 GRU 的核心计算包括更新门&#xff08;update gat…

【杨辉三角,递归】

参考代码&#xff1a; #include<bits/stdc.h> using namespace std; int pos(int x,int y) {if(y1||xy)return 1;elsereturn pos(x-1,y-1)pos(x-1,y); }int main() {int n0; //若输入的行数太大&#xff0c;三角形的样式会不规则&#xff0c;因此这里用while来控制输入的…

单片机的中断

中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置 当中央处理机CPU正在处理某件事的时候外界发生紧急事件请求&#xff0c;要CPU暂停当前的工作&#xff0c;转而去处理这个紧急事件&#xff0c;处理完以后&#xff0c;再回到原来中断的地方&#xff0c;继续原来的工作…

环形链表的判断方法与原理证明

&#xff08;题目来源&#xff1a;力扣&#xff09; 一.判读一个链表是否是环形链表 题目&#xff1a; 解答&#xff1a; 方法&#xff1a;快慢指针法 内容&#xff1a;分别定义快慢指针&#xff08;fast和slow&#xff09;&#xff0c;快指针一次走两步&#xff0c;慢指…

2024 年 7 款最好的 iOS 系统修复软件

您的 iOS 设备是否时不时地出现问题&#xff1f;因此屏幕卡住&#xff0c;或者无法退出恢复模式&#xff1f; 即使是最新的 iPhone 型号&#xff0c;也可能存在大量错误。解决所有这些错误的最佳且安全的方法是使用iOS系统修复工具&#xff0c;让您的修复工作变得更加轻松。 …

KIE基于图模型的关键信息抽取源码详解

1.数据集准备 下载数据集 https://download.openmmlab.com/mmocr/data/wildreceipt.tar WildReceiptOpenset 准备好 WildReceipt。 转换 WildReceipt 成 OpenSet 格式: # 你可以运行以下命令以获取更多可用参数: # python tools/dataset_converters/kie/closeset_to_opens…