计算机网络课程设计实验报告.docx
- 文档编号:10986059
- 上传时间:2023-02-24
- 格式:DOCX
- 页数:25
- 大小:139.98KB
计算机网络课程设计实验报告.docx
《计算机网络课程设计实验报告.docx》由会员分享,可在线阅读,更多相关《计算机网络课程设计实验报告.docx(25页珍藏版)》请在冰豆网上搜索。
计算机网络课程设计实验报告
计算机网络课程设计实验报告
中南大学课程设计报告
课程:
计算机网络课程设计
题目:
基于Winpcap的网络流量统计分析
指导教师:
张伟
第1章总体设计
1、实体类设计--------P3
2、功能类设计--------P3
3、界面设计--------P3
第2章详细设计
1、实体类实现--------P4
2、功能类实现--------P4
3、界面实现--------P5
第3章源代码清单及说明
一、CaptureUtil.java--------P7
二、MyPcapPacketHandler.java--------P9
三、PacketMatch.java--------P9
四、Windows.java--------P13
第4章运行结果--------P19
第五章心得体会--------P21
第1章总体设计
1、实体类设计
TCP、UPD、ICMP、ARP、广播数据包五个包的数据结构设计
2、功能类设计
(1)网卡获取
(2)包的抓捕
(3)包的处理
3、界面设计
(1)布局
(2)按钮功能连接
第2章第二章详细设计
一、实体类实现
TCP、UPD、ICMP、ARP、广播数据包五个包的数据结构设计。
本程序采用Java编写,基于win10pcap。
Win10pcap是winpcap在win10系统上的适用版本。
Java对于winpcap使用jnetpcap进行支持。
对于TCP、UPD、ICMP、ARP、广播数据包五种类型的包,在jnetpcap的jar包中大部分已经封装好了相关的实体类型。
对应如下:
ARP实体类:
work.Arp;
UPD实体类:
work.Icmp;
IP实体类:
work.Ip4;
TCP实体类:
org.jnetpcap.protocol.tcpip.Tcp;
UDP实体类:
org.jnetpcap.protocol.tcpip.Udp;
而对于其中的广播数据包,其判断我利用捕获到的IP包的目的地址进行判断,若其目的地址为255.255.255.255,则认为其为广播数据包。
2、功能类实现
(1)网卡获取
电脑上的包的发送与接受都得通过网卡来进行,所以为了完成局域网数据包的捕获和统计,我首先要做的是获取到电脑上的网卡列表,然后选择一个网卡进行包的捕获。
而相关代码在jnetpcap的官网的示例代码1中可以找到,从中可以学习到的是jnetpcap的各种使用方法。
在我电脑上可以捕获到三个网卡,一个是本机自身的物理网卡,另外两个是虚拟机模拟出的虚拟网卡。
(2)包的抓捕
Jnetpcap中包的抓捕也是有着固定的格式的,这在官网的示例代码中也是可以找到的,只要设置好相关的参数,就可以进行抓捕
具体方法如下,利用Pcap对象的loop方法。
就是实例化一个Pcap对象,然后调用其loop方法。
第一个参数arg0代表循环次数,第二个参数就是传入一个PcapPaketHandler或其子类的对象,这个对象类型是要由我们自己编写的对包处理的方法。
(3)包的处理
在这里对捕获的包的处理我是编写了一个PcapPacketHandler的子类,然后重写了nextPacket()方法。
在这个方法里我把捕获到的包当作参数传递个具体的处理方法packetMatch.handlePacket(packet)。
packetMatch.handlePacket(packet)方法是由我自己编写的。
handlePacket是packetMatch的一个静态方法,可以直接调用。
在这个方法里面,它会把捕获到的包的包头和TCP、UPD、ICMP、ARP、广播数据包五种类型的包的包头进行一一比较,以确认是否抓到了了相对应的包。
这儿还用到的就是jnetpcap的内部的一个方法,就是packet.hasHeader(arg0),通过在arg0传入已在jnetpcap里封装好的包的类型的实例,可以很好的判断该包是属于什么包类型的,是TCP、UPD、ICMP、ARP还是广播数据包。
然后内部对于各种包的信息的输出也有很好的支持,可以直接使用相应的toString方法,就可以输出各种相关信息。
(4)网络流量统计
对于各个捕获到的包,分别针对各种类型的包设计了一个Double变量用于统计其传送过来相应包头的大小,并在停止抓包后将统计的数据输出在最下方的TextArea里面。
3、界面实现
本程序在设计GUI时使用了Java的一个很好的插件WindowBuilder。
(1)布局
一开始使用BorderLayout布局,安排好各个按钮位置,文本框位置。
后来采用Absolutelayout,并将窗口大小固定化。
在布局的最上方是一个JToolBar的实例对象,其中放置有选择网卡、开始抓包、停止抓包、清空记录等四个选项,中间是两个带滚动条的多行文本框,左边的用于显示捕获的包的列表,右边用于显示左边的我们选中的包的具体信息。
最下方会在停止抓包按钮生效后输出总的抓包情况。
(2)按钮功能连接
在布局的最上方是一个JToolBar的实例对象,其中放置有选择网卡、开始抓包、停止抓包、清空记录等四个选项,其中选择网卡的功能具体由JComboBox(多文本选择框)上的选项决定,这个多文本选择框监听着网卡获取的方法,它会从该方法获得一个网卡列表,然后将其文本输出。
开始抓包的方法所对应的事件是抓包的事件,并且该抓包事件是个并发的进程。
因为如果不将其设置为并发进程,其会使其它事件一直阻塞,甚至连停止抓包都做不到。
停止抓包的事件其实是改变了开始抓包中的一个标志位,让其为假。
该标志为为真,抓包程序会一直进行,该标志为为假,抓包停止。
下方两个文本框,左边的文本框监听的是开始抓包这个事件,当这个事件开始,这个事件会向文本框传输捕获到的包的列表,然后让其显示。
而右边的文本框监听的是左边文本框我们选中的内容的相应事件。
因为对于我们捕获到的包我进行了编号,当我们在左边的文本框选中了一个包之后,左边的文本框对应的包的序号会被右边的文本框获取,用于在一个列表中根据序号查找到相对应的包的详细内容,然后将其输出。
统计功能的实现是在每个包的具体处理时,在处理包的方法类中已经有定义好几个静态变量用于计数,每个包具体处理时,将相对应的包类型数量加一即可。
还定义了其它的变量用于统计流量大小,也是在每个包具体处理时,将相对应的包的大小加到相对应的静态变量上即可。
第3章源代码清单及说明
CaptureUtil.java
//该类负责网卡列表的获取、包的捕获、抓包程序的停止
packageutil;
importjava.util.ArrayList;
importjavax.swing.JOptionPane;
importorg.jnetpcap.Pcap;
importorg.jnetpcap.PcapIf;
importentity.Windows;
publicclassCaptureUtilextendsThread{
privatestaticbooleanflag=true;
publicstaticintnumber=2;
privatestaticStringBuildererrbuf=newStringBuilder();//用于存储任何错误信息
//此方法用于获取设备上的网卡设施
publicstaticArrayList
CaptureUtil.flag=false;
//下面有部分代码来自jnetpcap官网的实例
ArrayList
//取得设备列表
intr=Pcap.findAllDevs(alldevs,errbuf);
if(r==Pcap.NOT_OK||alldevs.isEmpty()){
JOptionPane.showMessageDialog(null,errbuf.toString(),"错误",JOptionPane.ERROR_MESSAGE);
returnnull;
}
returnalldevs;
}
//此方法用于选取网卡并捕获包
publicstaticvoidCapturePacket(ArrayList
CaptureUtil.flag=true;
PcapIfdevice=alldevs.get(number);
/*System.out.printf("\nChoosing'%s'onyourbehalf:
\n",device
.getDescription());*/
//打开选中的设备
intsnaplen=Pcap.DEFAULT_SNAPLEN;//默认长度为65535
intflags=Pcap.MODE_PROMISCUOUS;//混杂模式,扑获所有类型的包
inttimeout=10*1000;//10secondsinmillis
Pcappcap=Pcap.openLive(device.getName(),snaplen,flags,timeout,errbuf);
if(pcap==null){
JOptionPane.showMessageDialog(null,errbuf.toString(),"错误",JOptionPane.ERROR_MESSAGE);
return;
}
PacketMatchpacketMatch=PacketMatch.getInstance();
MyPcapPacketHandler
while(CaptureUtil.flag){
pcap.loop(1,myhandler,"/njnetpcap");
}
pcap.close();
}
publicvoidrun(){
CaptureUtil.CapturePacket(CaptureUtil.CaptureNet());
}
publicstaticvoidStopCapturePacket(){
CaptureUtil.flag=false;
}
publicstaticvoidClearPacket(){
PacketMatch.numberOfPacket=0;
PacketMatch.hm.clear();
Windows.lItems.clear();
PacketMatch.numberOfArp=0;
PacketMatch.numberOfTcp=0;
PacketMatch.numberOfUdp=0;
PacketMatch.numberOfIcmp=0;
PacketMatch.numberOfWideSpread=0;
}
}
MyPcapPacketHandler.java
//该类是PcapPacketHandler的子类,重写了nextPacket方法
packageutil;
importorg.jnetpcap.packet.PcapPacket;
importorg.jnetpcap.packet.PcapPacketHandler;
publicclassMyPcapPacketHandler
@Override
publicvoidnextPacket(PcapPacketpacket,Objectarg1){
PacketMatchpacketMatch=PacketMatch.getInstance();
packetMatch.handlePacket(packet);
}
}
PacketMatch.java
//该类是包处理
packageutil;
importjava.util.HashMap;
importorg.jnetpcap.packet.PcapPacket;
importwork.Arp;
importwork.Icmp;
importwork.Ip4;
importorg.jnetpcap.protocol.tcpip.Tcp;
importorg.jnetpcap.protocol.tcpip.Udp;
importentity.Windows;
publicclassPacketMatch{
publicstaticHashMaphm=newHashMap();
publicstaticintnumberOfPacket=0;
privatestaticPacketMatchpm;
privateIcmpicmp=newIcmp();
privateTcptcp=newTcp();
privateUdpudp=newUdp();
privateArparp=newArp();
privateIp4ip4=newIp4();
publicstaticdoubletotalOfIcmp=0;
publicstaticdoubletotalOfTcp=0;
publicstaticdoubletotalOfUdp=0;
publicstaticdoubletotalOfArp=0;
publicstaticdoubletotalOfSpread=0;
publicstaticdoubletotalOfIp=0;
publicstaticintnumberOfWideSpread=0;
publicstaticintnumberOfUdp=0;
publicstaticintnumberOfTcp=0;
publicstaticintnumberOfIcmp=0;
publicstaticintnumberOfArp=0;
publicstaticPacketMatchgetInstance(){
if(pm==null){
pm=newPacketMatch();
}
returnpm;
}
publicvoidhandlePacket(PcapPacketpacket){
//以下四个包都已可以正确捕获
PacketMatch.totalOfIp+=packet.getTotalSize()/(1024.0*1024.0);
if(packet.hasHeader(icmp)){
handleIcmp(packet);
}
if(packet.hasHeader(arp)){
handleArp(packet);
}
if(packet.hasHeader(tcp)){
handleTcp(packet);
}
if(packet.hasHeader(udp)){
handleUdp(packet);
}
//广播数据包的捕获
if(packet.hasHeader(ip4)){
handleIp4(packet);
/*以下为实验IP地址的获取
packet.getHeader(ip4);
System.out.println(ip4.toString());
byte[]destinations=newbyte[4];
ip4.destinationToByteArray(destinations);
byte[]sources=newbyte[4];
ip4.sourceToByteArray(sources);
System.out.println("ip4destination:
"+destinations);
System.out.println("ip4resource:
"+sources);
System.out.println("ip4destination:
"+ip4.destinationToInt());
System.out.println("ip4resource:
"+ip4.sourceToInt());
System.out.println("ip4destination:
"+PacketMatch.intToIp(ip4.destinationToInt()));
System.out.println("ip4resource:
"+PacketMatch.intToIp(ip4.sourceToInt()));
*/
}
}
privatevoidhandleIp4(PcapPacketpacket){
packet.getHeader(ip4);
if(PacketMatch.intToIp(ip4.destinationToInt()).equals("255.255.255.255")){
//这是一个广播数据包
System.out.println("收到一个广播数据包");
Windows.lItems.add(numberOfPacket,"广播数据包");
hm.put(numberOfPacket,"这是一个广播数据包!
");
numberOfWideSpread++;
totalOfSpread+=ip4.getLength()/1024.0;
numberOfPacket++;
}
}
privatevoidhandleUdp(PcapPacketpacket){
packet.getHeader(udp);
System.out.println("udp来源端口"+udp.toString());
hm.put(numberOfPacket,udp.toString());
Windows.lItems.add(numberOfPacket,"udp");
numberOfUdp++;
totalOfUdp+=udp.getLength()/1024.0;
numberOfPacket++;
}
privatevoidhandleTcp(PcapPacketpacket){
packet.getHeader(tcp);
System.out.println(tcp.toString());
hm.put(numberOfPacket,tcp.toString());
Windows.lItems.add(numberOfPacket,"tcp");
numberOfTcp++;
totalOfTcp+=tcp.getLength()/1024.0;
numberOfPacket++;
}
privatevoidhandleIcmp(PcapPacketpacket){
packet.getHeader(icmp);
System.out.println("icmp:
"+icmp.toString());
hm.put(numberOfPacket,icmp.toString());
Windows.lItems.add(numberOfPacket,"icmp");
numberOfIcmp++;
totalOfIcmp+=icmp.getLength()/1024.0;
numberOfPacket++;
}
privatevoidhandleArp(PcapPacketpacket){
packet.getHeader(arp);
System.out.println("arp:
"+arp.toString());
hm.put(numberOfPacket,arp.toString());
Windows.lItems.add(numberOfPacket,"arp");
numberOfArp++;
totalOfArp+=arp.getLength()/1024.0;
numberOfPacket++;
}
//以下函数将Int类型转化为Ip地址
publicstaticStringintToIp(intipInt){
returnnewStringBuilder().append(((ipInt>>24)&0xff)).append('.').append
((ipInt>>16)&0xff).append('.').append
((ipInt>>8)&0xff).append('.').append
((ipInt&0xff)).toString();
}
}
Windows.java
//该类是GUI界面设计
packageentity;
importjava.awt.Color;
importjava.awt.EventQueue;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.ItemEvent;
importjava.awt.event.ItemListener;
importjava.util.ArrayList;
importjavax.swing.AbstractAction;
importjavax.swing.Action;
importjavax.swing.BorderFactory;
importjav
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 计算机网络 课程设计 实验 报告