最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

即时:Java + Jpcap实现监控 IP包流量

来源:博客园

Java + Jpcap实现监控 IP包流量

说明:本设计是计算机网络课程的课设,因为代码是提前实现的,本博客于后期补上,又因为代码没写注释自己也看不懂了,所以,仅供参考,就当提供一种实现方式。


(相关资料图)

文中提供的《Jpcap中文API文档》来源于网络,本文仅用于学习交流,如有侵权,可联系我进行删除。

效果图:

1)课程设计要求

1.1 课程设计目的

通过本实课程设计,有助于理解 IP包的格式和加深对 IP 协议的理解。

1.2 课程设计要求

编制程序,监控网络,捕获一段时间内网络上的 IP 数据包,按 IP 数据包的源地址统计出该源地址在该时间段内发出的 IP 包的个数,将其写人日志文件中或用图形表示出来(建议用图形表示出统计结果)。

1.3 程序的具体要求如下

用命令行运行: IPStatistic time logfile

其中, IPStatistic 是程序名; time 是设定的统计时间间隔(单位为分钟,比如,2表示2分钟); logfile 表示统计结果写人的日志文件名(若用图形表示统计结果则可以不选这个参数)。

2)编码前的准备

2.1 技术点

后端:springboot,Jpcap

前端:vue2,ECharts

说明:Jpcap是一个能够捕获、发送网络数据包的java类库包。

2.2 环境搭建

2.2.1 事先说明和下载链接

ps:网上大部分都是Jpcap+winpcap,但是winpcap太老了,大概率在Windows10和Windows11上会出问题,当时也踩了不少坑,这里推荐使用npcap

winocap网址:https://www.winpcap.org/

Npcap网址:https://npcap.com/

从图中可以看出,winocap已经不再支持,推荐使用npcap

进入Npcap官网下载即可

2.2.2 资源下载

链接:https://pan.baidu.com/s/1y6u-V-FPwOgIxC9ZoAD7yg提取码:1111

内容:

  • Jpcap中文API文档
  • npcap-1.72.exe
  • Jpcap.dll
  • jpcap.jar
  • network_vue(前端代码,需要自己装包:npm install
  • network_course_design(Java代码)

2.2.3安装

重点1、3、4步

  1. Npcap.exe正常进行安装即可

  2. 创建一个普通springboot项目

  3. 在项目中导入Jpcap.jar

  1. Jpcap.dll放到JDK安装路径下的 /jre/bin 目录下(我这里好像没有放也可以运行,可以试一下)

  2. 前端就是一个普普通通的VUE+ECharts项目

3)编码

重要提示:当时为了赶工,其中的逻辑很有问题,现在的评价就一个字,烂,非常烂!!!看看关键实现就行。

这里推荐看这篇博客,写的很好,里面对重要字段进行了说明:https://www.cnblogs.com/shy-huiying/p/5636274.html

3.1 后端实现

3.1.1 获得本机所有网卡接口信息

Jpcap提供了方法JpcapCaptor.getDeviceList()完成这个任务,该方法返回一组NetworkInterface对象。

NetworkInterface[] devices = JpcapCaptor.getDeviceList();

/***  这里是controller层 * 获得所有网卡接口 * @return List */@RequestMapping("/info")public Object getNetworkCard(){    // 获取网络接口列表,返回所有的网络设备数组;    NetworkInterface[] devices = JpcapCaptor.getDeviceList();    if (devices.length == 0) {        return "无网卡信息";    }else{        List netList = new ArrayList<>();        int index = 0;        for (NetworkInterface n : devices) {            //NetworkCardPojo是自己编写的实体类,包含网卡接口索引和网卡接口名两个属性            NetworkCardPojo networkCardPojo = new NetworkCardPojo();            networkCardPojo.setIndex(index++);            networkCardPojo.setDescription(n.description);            //networkCardPojo.setNetworkInterface(n);            netList.add(networkCardPojo);        }        return netList;    }}
public class NetworkCardPojo {    private Integer index;    private String description;    //private NetworkInterface NetworkInterface;}

返回到前端的数据:

3.1.2 得到指定网卡的具体信息

  • NetworkInterface[] devices = JpcapCaptor.getDeviceList();得到多有网卡信息
  • devices[index].addresses;根据前端传入的网卡接口索引得到指定网卡接口的信息。
/**    *  这里是controller层     *  打印选择网卡的IP地址和子网掩码;     * @param index     * @return     */    @RequestMapping("/local")    public LocalParameterPojo getLocalParameter(@ProbeParam("index") Integer index){        NetworkInterface[] devices = JpcapCaptor.getDeviceList();        //根据传入的网卡索引获取该网卡接口所属的IP地址        NetworkInterfaceAddress[] device = devices[index].addresses;        //LocalParameterPojo是自己编写的实体类,包含本机IP地址、子网掩码、网络连接类型        LocalParameterPojo local = new LocalParameterPojo();        if (device.length>0){            local.setIpv4(device[0].address);            local.setSubnetMask(device[0].subnet);            local.setNetType(devices[0].datalink_description);        }else {            local.setNetType("该网卡接口不可用,请尝试切换其他网卡接口!");        }        return local;    }

LocalParameterPojo实体类,注意部分字段是InetAddress类型

public class LocalParameterPojo {    private InetAddress ipv4;            //本机IP地址    private InetAddress SubnetMask;      //子网掩码    private String netType;         //网络连接类型}

3.1.3 监控ip包数据

因为一个ip地址会发送多个ip包,这里主要是将ip包进行分组统计:

IP地址--累计IP包数量--累计IP包大小

这里写的不好,有些问题,甚至问题很大,后面想到有更好的解决方法,但是没有尝试过,就不写了

/**     * 这里是controller层     * 开启监控ip包流量监控     * @param index     * @return     */    @RequestMapping("/start")    public List startGetPacket(@ProbeParam("index") Integer index){        targetParameter.startThread(index);        //根据Ip地址分组        Map mapAll = new HashMap<>();        System.out.println("ip count:"+targetParameter.getTargetMap().size());        for (int i=0;i targetList = new ArrayList<>();        for (Map.Entry map:mapAll.entrySet()){            TargetParameterPojo targetPojo = new TargetParameterPojo();            targetPojo.setSourceIp(map.getKey());            targetPojo.setSize(map.getValue().getSize());            targetPojo.setCount(map.getValue().getCount());            targetList.add(targetPojo);        }        return targetList;    }    /**     * 关闭监控ip包流量     * @return     */    @RequestMapping("/stop")    public int stopsGetPacket(){        int flag = targetParameter.getTargetMap().size();        if(flag>1){            targetParameter.stopThread();            return 1;        }else {            return 0;        }    }

service层

@Servicepublic class TargetParameter implements Runnable{    //数据统计要用到的list    private static List> targetMap = new ArrayList<>();    private boolean flag = true;    private TargetParameter tp;    private Thread thread;    private Integer isOff=0;    public TargetParameter(JpcapCaptor jpcap) {        this.jpcap = jpcap;    }    private JpcapCaptor jpcap = null;    public TargetParameter() {    }    public List> getTargetMap() {        return targetMap;    }    @Override    public void run() {        //只要不停止就一直进行抓包        while (flag){            IPPacket ipPacket = (IPPacket) jpcap.getPacket();            if (ipPacket!=null){                Map map = new HashMap<>();                map.put(ipPacket.src_ip,ipPacket.len);                targetMap.add(map);            }            // 回调方法            //jpcap.processPacket(-1, new CallbackService());        }    }    /**     * 开启线程方法     */    public void startThread(Integer index){        if (isOff==0){            try {                NetworkInterface[] devices = JpcapCaptor.getDeviceList();                //获得了JpcapCaptor实例就可以用来捕获来自网络接口的数据包。                //网卡索引,捕获数据包大小,是否开启混杂模式(混杂模式会捕获到数据表),超时                jpcap = JpcapCaptor.openDevice(devices[index], 1024, true, 1000);                // 在捕获前先设置过滤;                jpcap.setFilter("ip", true);            } catch (IOException e) {                e.printStackTrace();                System.out.println("抓取数据包时出现异常!!");            }            tp = new TargetParameter(jpcap);            //创建一个抓抓包线程,保证一直进行抓包            thread = new Thread(tp);            thread.start();            System.out.println("thread.getName():"+thread.getName());            isOff++;        }    }    /**     * 关闭线程并清空List     */    public void stopThread(){        isOff=0;        tp.flag=false;        targetMap.clear();        System.out.println(targetMap);    }}

Pojo:

public class TargetParameterPojo {    private InetAddress sourceIp;    private Integer count;    private Integer size;}
public class IpGroup {    private Integer size;    private Integer count;}

3.1.4 目录结构

3.2 前端实现

前端实现很简单,主要是数据渲染,这里说一下我的思路:

  1. 设定一个计时器,每隔1秒钟就请求一次数据,从而进行数据更新(axios实现)
  2. 可根据需要对数据进行排序和截取,比如截取前20条数据进行排序(数据条数太多会造成图形不美观)
  3. 优化:对开启和关闭按钮进行控制,防止重复请求和重复关闭

4)END

资源下载

链接:https://pan.baidu.com/s/1y6u-V-FPwOgIxC9ZoAD7yg提取码:1111

内容:

  • Jpcap中文API文档
  • npcap-1.72.exe
  • Jpcap.dll
  • jpcap.jar
  • network_vue(前端代码,需要自己装包:npm install
  • network_course_design(Java代码)

重要:请勿学习如上代码的写法,那时候vue正在学,还行学完,代码冗余严重。

本博客仅仅提供解决方法!欢迎讨论,感谢批评指正。

关键词: