具有界面,能够实现基本功能(查看网卡信息,开始抓包,暂停抓包(开始抓包后“开始”按钮变为“暂停”,清空界面内容,退出,以及过滤器功能的简单实现)),界面如下图:
package packetCapture;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import java.awt.*;
* 流式布局
public class JpCapFrame extends JFrame {
private static DefaultTableModel model;
private static JTextField filterField;
private JTextArea showArea;
private JButton startBtn;
private JButton checkBtn;
private JButton exitBtn;
private JButton clearBtn;
public JpCapFrame() {
super();
initGUI();
public static DefaultTableModel getModel() {
return model;
public JTextArea getShowArea() {
return showArea;
public JButton getStartBtn() {
return startBtn;
public JButton getCheckBtn() {
return checkBtn;
public JButton getExitBtn() {
return exitBtn;
public JButton getClearBtn() {
return clearBtn;
public static JTextField getFilterField() {
return filterField;
private void initGUI() {
Font font1 = new Font("宋体", Font.BOLD, 15);
Font font4 = new Font("宋体", Font.BOLD, 14);
Font font2 = new Font("宋体", Font.PLAIN, 16);
Font font3 = new Font("微软雅黑", Font.PLAIN, 16);
setSize(1550, 1000);
setVisible(true);
setTitle("Captor");
Container container = this.getContentPane();
JPanel pane = new JPanel();
pane.setBounds(0, 0, 775, 150);
pane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
pane.setPreferredSize(new Dimension(775, 27));
checkBtn = new JButton("查看网卡信息");
checkBtn.setFont(font4);
checkBtn.setBounds(0, 0, 50, 0);
pane.add(checkBtn);
startBtn = new JButton("开始");
startBtn.setFont(font4);
startBtn.setBounds(0, 0, 50, 0);
pane.add(startBtn);
clearBtn = new JButton("清空");
clearBtn.setFont(font4);
clearBtn.setBounds(0, 0, 50, 0);
pane.add(clearBtn);
exitBtn = new JButton("退出");
exitBtn.setFont(font4);
exitBtn.setBounds(0, 0, 50, 0);
pane.add(exitBtn);
JPanel panelTest = new JPanel();
panelTest.setBounds(775, 0, 775, 150);
panelTest.setPreferredSize(new Dimension(775, 27));
panelTest.setLayout(new FlowLayout(FlowLayout.RIGHT, 20, 0));
JLabel filter = new JLabel("Filter:");
filter.setFont(font1);
filter.setBounds(0, 0, 500, 0);
filterField = new JTextField(50);
filterField.setBounds(200, 0, 500, 0);
panelTest.add(filter);
panelTest.add(filterField);
//中部主体内容显示区
String[] name = {"No.", "Time", "Source", "Destination", "Protocol", "Length", "Info"};
//model = new DefaultTableModel();
//model.setColumnIdentifiers(name);
JTable table = new JTable(model);
JTableHeader tableHeader = table.getTableHeader();
tableHeader.setFont(font1);
table.setFont(font2);
table.setRowHeight(20);
model = (DefaultTableModel) table.getModel();
model.setColumnIdentifiers(name);
table.setEnabled(false);
JScrollPane jScrollPane = new JScrollPane(table);
jScrollPane.setBounds(0, 300, 1550, 600);
JPanel pane2 = new JPanel();
pane2.setLayout(new BorderLayout());
pane2.setPreferredSize(new Dimension(1550, 300));
showArea = new JTextArea(5, 5);
//showArea.setBounds(0,0,1200,300);
//showArea.setText("Test");
showArea.setEditable(false);
showArea.setLineWrap(false);
showArea.setFont(font3);
//showArea.setBackground(Color.GRAY);
//pane2.add(showArea);
pane2.setSize(10, 10);
pane2.setBounds(0, 0, 1, 1);
//给textArea添加滚动条
JScrollPane scrollPane = new JScrollPane(showArea);
scrollPane.setBounds(0, 0, 1, 1);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
pane2.add(scrollPane, BorderLayout.CENTER);
scrollPane.setViewportView(showArea);
container.add(jScrollPane, BorderLayout.CENTER);
container.add(pane, BorderLayout.NORTH);
container.add(panelTest, BorderLayout.NORTH);
container.add(pane2, BorderLayout.SOUTH);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
package packetCapture;
import jpcap.JpcapCaptor;
import jpcap.NetworkInterface;
import java.io.IOException;
public class JpCapMain implements Runnable {
JpCapFrame frame;
JpcapCaptor jpcap = null;
private static Thread thread = null;
private static boolean pause = true;
public JpCapMain() {
//创建界面
frame = new JpCapFrame();
frame.setVisible(true);
//绑定网络设备
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
int caplen = 1512;
boolean promiscCheck = true;
WIFI:3
(不同设备对应的不一样)
int device = 1;
try {
jpcap = JpcapCaptor.openDevice(devices[device], caplen, promiscCheck, 50);
} catch (IOException e) {
e.printStackTrace();
frame.getCheckBtn().addActionListener(e -> {
frame.getShowArea().append("当前设备全部网络设备信息为: \n");
for (NetworkInterface n : devices) {
System.out.println(n.name + " | " + n.description);
frame.getShowArea().append(n.name + " | " + n.description + "\n");
//System.out.println("-------------------------------------------");
frame.getShowArea().append(printSeparator(110, 0));
frame.getShowArea().append("\n当前使用网卡信息: " + devices[device].name + " | " + devices[device].description + "\n");
frame.getShowArea().append(printSeparator(110, 1));
frame.getStartBtn().addActionListener(e -> {
if (pause) {
if (thread == null) {
frame.getShowArea().append(" 开始抓包,抓取范围为:" + JpCapFrame.getFilterField().getText() + " ……\n");
thread = new Thread(this);
thread.setPriority(Thread.MIN_PRIORITY);
//thread.sleep(100);
thread.start();
pause = false;
frame.getStartBtn().setText("暂停");
} else {
frame.getStartBtn().setText("暂停");
pause = false;
frame.getShowArea().append(" 继续抓包,抓取范围为:" + JpCapFrame.getFilterField().getText() + " ……\n");
synchronized (thread) {
thread.notify();
} else {
pause = true;
frame.getStartBtn().setText("开始");
frame.getShowArea().append(" 暂停抓包\n");
frame.getClearBtn().addActionListener(e -> {
frame.getShowArea().setText("");
frame.getModel().setRowCount(0);
frame.getExitBtn().addActionListener(e -> {
System.exit(0);
public static void main(String[] args) {
new JpCapMain();
@Override
public void run() {
try {
new JpCapPacket(jpcap).capture();
thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
* @param separator "-"的数量
* @param line "\n"的数量
* @return
public String printSeparator(int separator, int line) {
String s = "";
String l = "";
for (int i = 0; i < separator; i++) {
s += "-";
for (int i = 0; i < line; i++) {
l += "\n";
return s + l;
public static Thread getThread() {
return thread;
public static boolean isPause() {
return pause;
}
本项目基本实现了抓包的功能,但是因为做的比较赶,所以还有很多功能没有完善。比如演示的时候发现有的同学有选择网卡的功能,我这里只做了查看网卡的功能,但是实现这个功能还是不难的,就是在devices[device]中想办法能够通过选择网卡与device(int)值对应。另外存在的问题就是界面比较简单,不是很美观,然后没有实现点开每一个数据包能够查看具体信息的功能,均还有待完善。