1、 中南大学课程设计汇报 课程:计算机网络课程设计 题目:基于Winpcap网络流量统计分析 指导老师:张伟 目录 第一章 总体设计 一、 实体类设计 --------P3 二、 功效类设计 --------P3 三、 界面设计 --------P3 第二章 具体设计 一、 实体类实现 --------P4
2、 二、 功效类实现 --------P4 三、 界面实现 --------P5 第三章 源代码清单及说明 一、CaptureUtil.java --------P7 二、MyPcapPacketHandler.java --------P9 三、PacketMatch.java --------P9 四、Windows.java --------P
3、13 第四章 运行结果 --------P19 第五章 心得体会 --------P21 第一章 总体设计 一、 实体类设计 TCP、UPD、ICMP、ARP、广播数据包五个包数据结构设计 二、 功效类设计 (1) 网卡获取 (2) 包抓捕 (3) 包处理 三、 界面设计 (1) 布局 (2) 按钮功效连接
4、 第二章 第二章 具体设计 一、实体类实现 TCP、UPD、ICMP、ARP、广播数据包五个包数据结构设计。 本程序采取Java编写,基于win10pcap。Win10pcap是winpcap在win10系统上适用版本。Java对于winpcap使用jnetpcap进行支持。对于TCP、UPD、ICMP、ARP、广播数据包五种类型包,在jnetpcapjar包中大部分已经封装好了相关实体类型。对应以下: ARP 实体类:work.Arp; UPD 实体类:work.Icmp; IP 实体类:work.Ip4; TCP 实体类:org.jnetpcap.protocol.tc
5、pip.Tcp; UDP 实体类:org.jnetpcap.protocol.tcpip.Udp; 而对于其中广播数据包,其判定我利用捕捉到IP包目标地址进行判定,若其目标地址为255.255.255.255,则认为其为广播数据包。 二、 功效类实现 (1)网卡获取 电脑上包发送和接收全部得经过网卡来进行,所以为了完成局域网数据包捕捉和统计,我首先要做是获取到电脑上网卡列表,然后选择一个网卡进行包捕捉。而相关代码在jnetpcap官网示例代码1中能够找到,从中能够学习到是jnetpcap多种使用方法。 在我电脑上能够捕捉到三个网卡,一个是本机本身物理网卡,另外两个是虚拟机模
6、拟出虚拟网卡。 (2) 包抓捕 Jnetpcap中包抓捕也是有着固定格式,这在官网示例代码中也是能够找到,只要设置好相关参数,就能够进行抓捕 具体方法以下,利用Pcap对象loop方法。就是实例化一个Pcap对象,然后调用其loop方法。第一个参数arg0 代表循环次数,第二个参数就是传入一个PcapPaketHandler或其子类对象,这个对象类型是要由我们自己编写对包处理方法。 (3) 包处理 在这里对捕捉包处理我是编写了一个PcapPacketHandler子类,然后重写了nextPacket()方法。在这个方法里我把捕捉到包看成参数传输个具体处理方法packetMat
7、ch.handlePacket(packet)。 packetMatch.handlePacket(packet)方法是由我自己编写。handlePacket是packetMatch一个静态方法,能够直接调用。在这个方法里面,它会把捕捉到包包头和TCP、UPD、ICMP、ARP、广播数据包五种类型包包头进行一一比较,以确定是否抓到了了相对应包。 这儿还用到就是jnetpcap内部一个方法,就是packet.hasHeader(arg0),经过在arg0传入已在jnetpcap里封装好包类型实例,能够很好判定该包是属于什么包类型,是TCP、UPD、ICMP、ARP还是广播数据包。 然后内部
8、对于多种包信息输出也有很好支持,能够直接使用对应toString方法,就能够输出多种相关信息。 (4) 网络流量统计 对于各个捕捉到包,分别针对多种类型包设计了一个Double变量用于统计其传送过来对应包头大小,并在停止抓包后将统计数据输出在最下方TextArea里面。 三、 界面实现 本程序在设计GUI时使用了Java一个很好插件WindowBuilder。 (1)布局 一开始使用Border Layout布局,安排好各个按钮位置,文本框位置。以后采取Absolute layout,并将窗口大小固定化。 在布局最上方是一个JToolBar实例对象,其中放置有选择网卡、开始抓包、
9、停止抓包、清空统计等四个选项,中间是两个带滚动条多行文本框,左边用于显示捕捉包列表,右边用于显示左边我们选中包具体信息。最下方会在停止抓包按钮生效后输出总抓包情况。 (2) 按钮功效连接 在布局最上方是一个JToolBar实例对象,其中放置有选择网卡、开始抓包、停止抓包、清空统计等四个选项,其中选择网卡功效具体由JComboBox(多文本选择框)上选项决定,这个多文本选择框监听着 网卡获取方法,它会从该方法取得一个网卡列表,然后将其文本输出。 开始抓包方法所对应事件是抓包事件,而且该抓包事件是个并发进程。因为假如不将其设置为并发进程,其会使其它事件一直阻塞,甚至连停止抓包全部做不到。
10、停止抓包事件其实是改变了开始抓包中一个标志位,让其为假。该标志为为真,抓包程序会一直进行,该标志为为假,抓包停止。 下方两个文本框,左边文本框监听是开始抓包这个事件,当这个事件开始,这个事件会向文本框传输捕捉到包列表,然后让其显示。而右边文本框监听是左边文本框我们选中内容对应事件。因为对于我们捕捉到包我进行了编号,当我们在左边文本框选中了一个包以后,左边文本框对应包序号会被右边文本框获取,用于在一个列表中依据序号查找到相对应包具体内容,然后将其输出。 统计功效实现是在每个包具体处理时,在处理包方法类中已经有定义好多个静态变量用于计数,每个包具体处理时,将相对应包类型数量加一即可。还定义了其
11、它变量用于统计流量大小,也是在每个包具体处理时,将相对应包大小加到相对应静态变量上即可。 第三章 源代码清单及说明 CaptureUtil.java //该类负责网卡列表获取、包捕捉、抓包程序停止 package util; import java.util.ArrayList; import javax.swing.JOptionPane; import org.jnetpcap.Pcap; import org.jnetpcap.PcapIf; import entity.Window
12、s;
public class CaptureUtil extends Thread{
private static boolean flag=true;
public static int number=2;
private static StringBuilder errbuf = new StringBuilder(); // 用于存放任何错误信息
//此方法用于获取设备上网卡设施
public static ArrayList
13、有部分代码来自jnetpcap官网实例
ArrayList
14、ESSAGE);
return null;
}
return alldevs;
}
//此方法用于选择网卡并捕捉包
public static void CapturePacket(ArrayList
15、vice .getDescription());*/ //打开选中设备 int snaplen = Pcap.DEFAULT_SNAPLEN;// 默认长度为65535 int flags = Pcap.MODE_PROMISCUOUS; // 混杂模式,扑获全部类型包 int timeout = 10 * 1000; // 10 seconds in millis Pcap pcap = Pcap.openLive(device.getName(), sna
16、plen, flags, timeout, errbuf); if (pcap == null) { JOptionPane.showMessageDialog(null,errbuf.toString(),"错误",JOptionPane.ERROR_MESSAGE); return; } PacketMatch packetMatch = PacketMatch.getInstance(); MyPcapPacketHandler
17、
18、pCapturePacket(){ CaptureUtil.flag=false; } public static void ClearPacket(){ PacketMatch.numberOfPacket=0; PacketMatch.hm.clear(); Windows.lItems.clear(); PacketMatch.numberOfArp=0; PacketMatch.numberOfTcp=0; PacketMatch.numberOfUdp=0; PacketMatch.numberOfIcmp=0;
19、PacketMatch.numberOfWideSpread=0;
}
}
MyPcapPacketHandler.java
//该类是PcapPacketHandler子类,重写了nextPacket方法
package util;
import org.jnetpcap.packet.PcapPacket;
import org.jnetpcap.packet.PcapPacketHandler;
public class MyPcapPacketHandler
20、@Override public void nextPacket(PcapPacket packet, Object arg1) { PacketMatch packetMatch = PacketMatch.getInstance(); packetMatch.handlePacket(packet); } } PacketMatch.java //该类是包处理 package util; import java.util.HashMap; import org.jnetpcap.packet.PcapPac
21、ket; import work.Arp; import work.Icmp; import work.Ip4; import org.jnetpcap.protocol.tcpip.Tcp; import org.jnetpcap.protocol.tcpip.Udp; import entity.Windows; public class PacketMatch { public static HashMap hm=new HashMap(); public static int numberOfPacket=0; private static Pack
22、etMatch pm; private Icmp icmp = new Icmp(); private Tcp tcp = new Tcp(); private Udp udp = new Udp(); private Arp arp= new Arp(); private Ip4 ip4=new Ip4(); public static double totalOfIcmp=0; public static double totalOfTcp=0; public static do
23、uble totalOfUdp=0; public static double totalOfArp=0; public static double totalOfSpread=0; public static double totalOfIp=0; public static int numberOfWideSpread=0; public static int numberOfUdp=0; public static int numberOfTcp=0; public static int numberOf
24、Icmp=0; public static int numberOfArp=0; public static PacketMatch getInstance() { if (pm == null) { pm = new PacketMatch(); } return pm; } public void handlePacket(PcapPacket packet) { //以下四个包全部已能够正确捕捉 PacketMatch.
25、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); }
26、 if (packet.hasHeader(udp)) { handleUdp(packet); } //广播数据包捕捉 if (packet.hasHeader(ip4)) { handleIp4(packet); /*以下为试验IP地址获取 packet.getHeader(ip4); System.out.println(ip4.toString()); byte[] destinations
27、new byte[4]; ip4.destinationToByteArray(destinations); byte[] sources=new byte[4]; ip4.sourceToByteArray(sources); System.out.println("ip4 destination:"+destinations); System.out.println("ip4 resource:"+sources);
28、System.out.println("ip4 destination:"+ip4.destinationToInt()); System.out.println("ip4 resource:"+ip4.sourceToInt()); System.out.println("ip4 destination:"+PacketMatch.intToIp(ip4.destinationToInt())); System.out.println("ip4 resource:"+Packet
29、Match.intToIp(ip4.sourceToInt())); */ } } private void handleIp4(PcapPacket packet) { packet.getHeader(ip4); if(PacketMatch.intToIp(ip4.destinationToInt()).equals("255.255.255.255")){ //这是一个广播数据包 System.out.println("收到一个广播数据包"); Windows.lItems.a
30、dd(numberOfPacket, "广播数据包"); hm.put(numberOfPacket, "这是一个广播数据包!"); numberOfWideSpread++; totalOfSpread+=ip4.getLength()/1024.0; numberOfPacket++; } } private void handleUdp(PcapPacket packet) { packet.getHeader(udp); System.out.println("udp起源端口"+udp.toString(
31、)); hm.put(numberOfPacket, udp.toString()); Windows.lItems.add(numberOfPacket, "udp"); numberOfUdp++; totalOfUdp+=udp.getLength()/1024.0; numberOfPacket++; } private void handleTcp(PcapPacket packet) { packet.getHeader(tcp); System.out.println(tcp.toStr
32、ing()); hm.put(numberOfPacket, tcp.toString()); Windows.lItems.add(numberOfPacket, "tcp"); numberOfTcp++; totalOfTcp+=tcp.getLength()/1024.0; numberOfPacket++; } private void handleIcmp(PcapPacket packet) { pa
33、cket.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++; } private void handleArp(PcapPacket packet)
34、 { 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地址 public sta
35、tic String intToIp(int ipInt){ return new StringBuilder().append(((ipInt>>24)&0xff)).append('.').append ((ipInt>>16)&0xff).append('.').append ((ipInt>>8)&0xff).append('.').append ((ipInt&0xff)).toString(); } } Windows.java //该类是GUI界面设计 package entity; import java.awt.
36、Color; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Bor
37、derFactory; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JToolBar; import javax
38、swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.jnetpcap.PcapIf; import util.CaptureUtil; import util.PacketMatch; public class Windows extends JFrame { private JPane
39、l contentPane; private final Action action = new SwingAction(); private final Action action_1 = new SwingAction_1(); private final Action action_2 = new SwingAction_2(); public static DefaultListModel lItems=new DefaultListModel(); private JList list = new JList(lItems); private f
40、inal Action action_3 = new SwingAction_3(); private JScrollPane jsp1=new JScrollPane(list); private JTextArea textArea = new JTextArea(); private JScrollPane jsp2=new JScrollPane(textArea); private JTextArea textArea_1 = new JTextArea(); /** * Launch the application. */ publi
41、c static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { Windows frame = new Windows(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */
42、public Windows() { setTitle("\u6293\u5305"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 692, 477); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); this.setResiza
43、ble(false); JToolBar toolBar = new JToolBar(); toolBar.setBounds(5, 5, 666, 23); contentPane.add(toolBar); JButton button = new JButton("\u9009\u62E9\u7F51\u5361"); toolBar.add(button); final JComboBox comboBox = new JComboBox(); comboBox.addActionListener(new Ac
44、tionListener() {
public void actionPerformed(ActionEvent e) {
String net=(String)comboBox.getSelectedItem();
ArrayList
45、){ CaptureUtil.number=i; System.out.println(CaptureUtil.number+":"+device.getDescription()); CaptureUtil.StopCapturePacket(); } i++; } } }); comboBox.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent arg0) { }
46、 }); toolBar.add(comboBox); JButton button_1 = new JButton("\u5F00\u59CB\u6293\u5305"); button_1.setAction(action_1); toolBar.add(button_1); JButton button_2 = new JButton("停止抓包"); button_2.setAction(action_2); button_2.addActionListener(new ActionListener() { public
47、 void actionPerformed(ActionEvent arg0) { } }); toolBar.add(button_2); JButton button_3 = new JButton("\u6E05\u7A7A\u8BB0\u5F55"); button_3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { } }); button_3.setAction(action_3); t
48、oolBar.add(button_3); Border brd=BorderFactory.createMatteBorder(1, 1, 2, 2, Color.black); list.setBorder(brd); list.addListSelectionListener(new ListSelectionListener(){ public void valueChanged(ListSelectionEvent arg0) { // TODO Auto-generated method stub textArea.se
49、tText(""); textArea.append((String)PacketMatch.hm.get(list.getSelectedIndex())); //以下两行用于检测 // System.out.println(list.getSelectedIndex()); // System.out.println((String)PacketMatch.hm.get(list.getSelectedIndex())); } }); jsp1.setBounds(5, 28, 258, 343); contentPane.add(jsp1); jsp2.setBounds(263, 28, 408, 343); contentPane.add(jsp2); textArea_1.setBounds(5, 371, 666, 67);






