说明:本设计是计算机网络课程的课设,因为代码是提前实现的,本博客于后期补上,又因为代码没写注释自己也看不懂了,所以,仅供参考,就当提供一种实现方式。
文中提供的资料来源于网络,本文仅用于学习交流,如有侵权,可联系我进行删除。
效果图:

通过本实课程设计,有助于理解 IP包的格式和加深对 IP 协议的理解。
编制程序,监控网络,捕获一段时间内网络上的 IP 数据包,按 IP 数据包的源地址统计出该源地址在该时间段内发出的 IP 包的个数,将其写人日志文件中或用图形表示出来(建议用图形表示出统计结果)。
用命令行运行: IPStatistic time logfile
其中, IPStatistic 是程序名; time 是设定的统计时间间隔(单位为分钟,比如,2表示2分钟); logfile 表示统计结果写人的日志文件名(若用图形表示统计结果则可以不选这个参数)。
后端:springboot,Jpcap
前端:vue2,ECharts
说明:
Jpcap是一个能够捕获、发送网络数据包的java类库包。
ps:网上大部分都是
Jpcap+winpcap,但是winpcap太老了,大概率在Windows10和Windows11上会出问题,当时也踩了不少坑,这里推荐使用npcap
winocap网址:https://www.winpcap.org/
Npcap网址:https://npcap.com/
从图中可以看出,winocap已经不再支持,推荐使用npcap

进入Npcap官网下载即可

链接:https://pan.baidu.com/s/1y6u-V-FPwOgIxC9ZoAD7yg
提取码:1111
内容:
npm install)重点1、3、4步
Npcap.exe正常进行安装即可
创建一个普通springboot项目
在项目中导入Jpcap.jar包

将Jpcap.dll放到JDK安装路径下的 /jre/bin 目录下(我这里好像没有放也可以运行,可以试一下)
前端就是一个普普通通的VUE+ECharts项目
重要提示:当时为了赶工,其中的逻辑很有问题,现在的评价就一个字,烂,非常烂!!!看看关键实现就行。
这里推荐看这篇博客,写的很好,里面对重要字段进行了说明:https://www.cnblogs.com/shy-huiying/p/5636274.html
Jpcap提供了方法JpcapCaptor.getDeviceList()完成这个任务,该方法返回一组NetworkInterface对象。
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
/**
* 这里是controller层
* 获得所有网卡接口
* @return List<String>
*/
@RequestMapping("/info")
public Object getNetworkCard(){
// 获取网络接口列表,返回所有的网络设备数组;
NetworkInterface[] devices = JpcapCaptor.getDeviceList();
if (devices.length == 0) {
return "无网卡信息";
}else{
List<NetworkCardPojo> 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;
}
返回到前端的数据:

/**
* 这里是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; //网络连接类型
}

因为一个ip地址会发送多个ip包,这里主要是将ip包进行分组统计:
IP地址--累计IP包数量--累计IP包大小
这里写的不好,有些问题,甚至问题很大,后面想到有更好的解决方法,但是没有尝试过,就不写了
/**
* 这里是controller层
* 开启监控ip包流量监控
* @param index
* @return
*/
@RequestMapping("/start")
public List<TargetParameterPojo> startGetPacket(@ProbeParam("index") Integer index){
targetParameter.startThread(index);
//根据Ip地址分组
Map<InetAddress, IpGroup> mapAll = new HashMap<>();
System.out.println("ip count:"+targetParameter.getTargetMap().size());
for (int i=0;i<targetParameter.getTargetMap().size();i++){
IpGroup ipGroup = new IpGroup();
for (InetAddress key:targetParameter.getTargetMap().get(i).keySet()){
Integer size = targetParameter.getTargetMap().get(i).get(key);
int count=1;
//检查 hashMap 中是否存在指定的 key 对应的映射关系。
if(mapAll.containsKey(key)){
Integer tempSize = mapAll.get(key).getSize();
size += tempSize;
Integer tempCount = mapAll.get(key).getCount();
count += tempCount;
}
ipGroup.setCount(count);
ipGroup.setSize(size);
mapAll.put(key,ipGroup);
}
}
// 将数据装到TargetParameterPojo
List<TargetParameterPojo> targetList = new ArrayList<>();
for (Map.Entry<InetAddress,IpGroup> 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层
@Service
public class TargetParameter implements Runnable{
//数据统计要用到的list
private static List<Map<InetAddress,Integer>> 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<Map<InetAddress, Integer>> getTargetMap() {
return targetMap;
}
@Override
public void run() {
//只要不停止就一直进行抓包
while (flag){
IPPacket ipPacket = (IPPacket) jpcap.getPacket();
if (ipPacket!=null){
Map<InetAddress,Integer> 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;
}


前端实现很简单,主要是数据渲染,这里说一下我的思路:
资源下载
链接:https://pan.baidu.com/s/1y6u-V-FPwOgIxC9ZoAD7yg
提取码:1111
内容:
npm install)重要:请勿学习如上代码的写法,那时候vue正在学,还行学完,代码冗余严重。
本博客仅仅提供解决方法!欢迎讨论,感谢批评指正。
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden
我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/
HashMap中为什么引入红黑树,而不是AVL树呢1.概述开始学习这个知识点之前我们需要知道,在JDK1.8以及之前,针对HashMap有什么不同。JDK1.7的时候,HashMap的底层实现是数组+链表JDK1.8的时候,HashMap的底层实现是数组+链表+红黑树我们要思考一个问题,为什么要从链表转为红黑树呢。首先先让我们了解下链表有什么不好???2.链表上述的截图其实就是链表的结构,我们来看下链表的增删改查的时间复杂度增:因为链表不是线性结构,所以每次添加的时候,只需要移动一个节点,所以可以理解为复杂度是N(1)删:算法时间复杂度跟增保持一致查:既然是非线性结构,所以查询某一个节点的时候
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.