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

news2024/11/24 10:03:01

项目介绍

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

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

各部分具体代码

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/1667244.html

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

相关文章

并发——进程

1. 程序 程序&#xff08;program&#xff09;是什么&#xff1f; 计算机程序&#xff08;computer program&#xff09;一般是指以某些程序设计语言编程&#xff0c;能够运行于某种目标体系结构上 程序 数据结构 算法 数据结构&#xff1a;用来表示人们思维对象的抽…

mysql的存储结构

一个表就是一个ibd文件 .ibd文件大小取决于数据和索引&#xff0c;在5.7之后才会为每个表生成一个独立表空间即一个ibd文件&#xff0c;在此之前&#xff0c;所有表默认下都会存储在“系统表空间”&#xff08;共享表空间&#xff09;&#xff0c;所有表都在一个ibd文件。 inn…

我的全新官网

科技语者-探索未来的语言和沟通 (chgskj.cn) 另外我还开放了一个网站科技语者-介绍页 (null.fit)

Verilog复习(四)| 组合逻辑

一位全加器结构描述&#xff1a; 数据流描述&#xff1a; 行为描述&#xff1a; 只要有事件发生&#xff08;列表中任何 信号有变化&#xff09;&#xff0c;就执行begin…end 的语句 。 always的事件控制方式 边沿触发 always (posedge clk) // clk从低电平->高&#x…

使用Flask构建POST请求的Web应用

文章目录 准备工作创建路由处理POST请求创建表单页面运行应用结论 在Web开发中&#xff0c;处理POST请求是一项常见任务&#xff0c;特别是在构建表单提交、用户注册和数据提交等功能时。Flask是一个简单而强大的Python Web框架&#xff0c;它提供了方便的工具来处理HTTP请求&a…

答辩PPT自述稿如何与幻灯片同步?笔灵AI一键生成功能解析

在我原本的认知里面&#xff0c;答辩PPT是要包含论文各个章节的&#xff0c;在答辩时需要方方面面都讲到的&#xff0c;什么摘要、文献综述、实证分析、研究结果样样不落。但是&#xff0c;这大错特错&#xff01; 答辩PPT环节时长一般不超过5分钟&#xff0c;老师想要的答辩P…

Postman工具介绍与安装

一、Postman介绍 Postman 乃是一款对 HTTP 协议予以支持的接口调试及测试工具&#xff0c;其突出特性在于功能强大&#xff0c;并且使用简便、易用性良好。不管是开发人员开展接口调试工作&#xff0c;还是测试人员进行接口测试任务&#xff0c;Postman 均属于首选工具之一。 接…

面试八股之Redis篇2——redis分布式锁

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…

图书馆APP开发解决方案

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言&#xff1a;pythonjavanode.jsphp均支持 运行软件…

blender 为世界环境添加纹理图像

1、打开世界环境配置项 2、点击颜色右侧的黄色小圆&#xff0c;选择环境纹理 3、打开一张天空图像 4、可以通过调整强度/力度&#xff0c;调整世界环境的亮度

ambari-server高可用配置方案

制品 https://kdocs.cn/l/cie4hSgvUunX 前置条件 环境需要支持VRRP协议 环境需要配置好yum源 变更影响面 变更不会影响其他组件 配置lb(需要客户侧配置并提供LB地址) 转发方式选择 主备 监听端口为8080、8440、8441 协议为tcp 后端监听选择kde-offline1为主 后端监听选择kde-…

QT-小项目:连接MY SQL数据库实现登录(下一章实现登录注册账号和忘记密码功能)

一、环境准备 1、下载MYSQL 64位&#xff0c;安装完成&#xff0c;制作简易数据库教程如下&#xff1a; MY SQL安装 2、QT 编译器使用 二、实现工程目录&#xff08;基于上一章基础上&#xff09; 三、源程序增加内容如下&#xff1a; login.cpp 增加头文件&#xff1a; #in…

MES系统与WMS集成方法(满分100学习资料)

导语 大家好&#xff0c;我是智能仓储物流技术研习社的社长&#xff0c;老K。专注分享智能仓储物流技术、智能制造等内容。 新书《智能物流系统构成与技术实践》 完整版文件和更多学习资料&#xff0c;请球友到知识星球【智能仓储物流技术研习社】自行下载 这份文件是关于MES系…

头歌C语言数据结构(队列的应用)

第1关&#xff1a;循环队列 任务描述 本关任务&#xff1a;编写一个循环队列&#xff0c;实现入队、出队操作&#xff0c;判断队空、队满等特殊情况。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;1.循环队列定义&#xff0c;2.入队、出队的定义&#xff…

别的项目都有 awesome 仓库,RT-Thread 也要有!

awesome 仓库是 GitHub 上用于收集某个项目或者某个语言相关的优质内容的仓库&#xff0c;例如中间件、新闻资讯、网站等。 作为 RT-Thread 开发者&#xff0c;看到别的项目都有 awesome 仓库&#xff0c;我想 RT-Thread 也应该有&#xff01; 于是&#xff0c;我创建一个 aw…

pyqt5将ui文件转为python文件

在pyqt5中使用 pyuic将ui文件转为py文件&#xff1a; 例如&#xff1a;将home.ui文件转为vio_detect.py文件&#xff0c;所需命令如下&#xff1a; pyuic5 -x home.ui -o vio_detect.py

Python彻底解决TypeError的问题

今天看到一个问题&#xff1a; TypeError: int() argument must be a string, a bytes-like object or a number, not list 代码是这样的&#xff1a; id int(os.path.split(imagePath)[1].split(.)[0]) 其实这个提示已经非常明显了&#xff0c;百度翻译过来就是&#xff1a…

废品回收微信小程序基于FastAdmin+ThinkPHP+UniApp(源码搭建/上线/运营/售后/更新)

一款基于FastAdminThinkPHPUniApp开发的废品回收系统&#xff0c;适用废品回收站、再生资源回收公司上门回收使用的小程序。 一、FastAdmin框架特色功能及优势 模块化开发&#xff1a;控制器、模型、视图、JS一一对应&#xff0c;使用RequireJS进行插件机制&#xff0c;支持插…

一文弄懂 Linux 系统调用函数之 exec 函数族

目录 简介函数原型参数说明返回值函数区别使用示例采用参数列表传递参数&#xff0c;以 execl 为例采用参数数组传递参数&#xff0c;以 execv 为例调用 PATH 下可执行文件&#xff0c;以 execlp 为例使用新的环境变量给新进程&#xff0c;以 execle 为例 更多内容 简介 exec …

【CMU 15-445】Proj4 Concurrency Control

Concurrency Control 通关记录Task1 TimestampsTask2 Storage Format and Sequential ScanTask3 MVCC ExecutorsTask3.1 Insert ExecutorTask3.2 CommitTask3.3 Update and Delete ExecutorTask3.4 Stop-the-world Garbage Collection Task4 Primary Key IndexTask4.0 Index Sc…