多线程端口扫描器+++Java课程设计报告+++源代码 - 图文

更新时间:2023-12-26 21:11:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

目 录

1 设计任务与要求 ........................................................................................... 2 2 系统功能描述 ............................................................................................... 2 2.1 功能概述 ................................................................................................ 2 2.2 本系统要实现的功能 ............................................................................ 2 3 系统总体设计 ............................................................................................... 3 3.1 总体分析 ................................................................................................ 3 3.2 界面设置构思图 .................................................................................... 3 3.3 界面使用设置构思 ................................................................................ 3 3.4 后台设计构思 ........................................................................................ 4 4 系统详细设计 ............................................................................................... 5 4.1 界面设计 ................................................................................................ 5 4.2 界面设计图 ............................................................................................ 5 4.3 后台设计 ................................................................................................ 6 5 实现与测试 ................................................................................................... 9 5.1 运行要求与环境 .................................................................................... 9 5.2 运行程序流程图 .................................................................................. 10 5.3 运行界面 .............................................................................................. 11 6 设计总结 ..................................................................................................... 13 参考文献 ......................................................................................................... 14 附件 ................................................................................................................. 14

多线程端口扫描器

1 设计任务与要求

加深对《Java面向对象程序设计》课程所学知识的理解,进一步巩固 Java语言的语法规则。分析系统的可行性,让系统有一个明确的方向,使开发更具合理性,并能分析出系统的具体流程,为后面的开发做好铺垫。明确本次课程设计所要用到的技术点并到网上搜索以及查阅相关的书籍来搜集资料。通过编写一个基于Java的应用系统综合实例,来掌握Java语言编程技巧。并学会编制结构清晰、风格良好的Java语言程序,从而具备解决综合性实际问题的能力,学会使用Java编程工具,如EditPlus,Eclipse等。

2 系统功能描述 2.1 功能概述

多线程端口扫描器是实现计算机的端口的扫描,只要在在前台设置好所要扫描的IP、起始端口、结束端口以及所要用到的线程数,点击扫描,就可以扫描到所输入IP地址主机的开放端口,并显示在主窗体中;点击退出,则可以退出该程序。IP设置应为所在主机的IP地址,起始端口和结束端口应为0~65535之间的一个数,且起始端口应小于结束端口的大小。线程数为0~200之间的一个数。点击开始后就会运行,直到扫描完毕显示出开放端口,如果没有开放端口,则只显示扫描完毕。

2.2 本系统要实现的功能

① 端口扫描功能:扫描开放的端口,并将扫描到的开放端口号送到前台。 ② 图像显示功能:显示界面图形。

③ 多线程功能:当客户端要求与服务器端建立连接时,服务器端就将用到多线程功能,为每一个建立起来的连接创建一个线程。

④ 异常抛出功能:对于明显的错误,能提示出错误的类型并结束程序的运行。

3 系统总体设计 3.1 总体分析

本程序分为前后台系统,后台系统用于扫描主机开放端口,并把节扫描的数据送至前台窗口显示;前台要显示扫描的结果,所以应为一个窗口,这个窗口应能够设置主机的IP地址,设置端口的开始端口、结束端口和线程数,并且还能够显示扫描的状态。在中央是显示结果的窗体。本程序还应能够有控制扫描的状态命令,附加设置最小化和关闭按钮。

3.2 界面设置构思图

图1 系统构思图

3.3 界面使用设置构思

当出现如图所示的界面时,填写好要扫描的IP地址,需要扫描的端口范围和线程数,单击命令提示按钮就可以开始扫描,扫描结果就会显示在中间的扫描结果显示区域,在扫描状态显示区就会显示是否扫描完毕。流程图如下:

界面出现 填写IP地址或者用默认的IP 设置扫描需要的线程数或者是用默认的线程数 单击命令按钮开始扫描 扫描结束,显示结果显示在结果显示区域 是 是否继续 否 退出结束

图2 系统构思流程图

3.4 后台设计构思

后台系统使用Scanner和Scan类,创建前台布局和创建扫描端口、事件处理,并且能对简单的错误进行判断,显示错误原因。调用数据处理包,处理异常情况;调用皮肤包,美化显示窗口。

4 系统详细设计 4.1 界面设计

本程序界面图形设计要能清楚显示扫描后的结果,并且能很好的体现出界面的整洁大方,但并不失去吸引人眼球的画面,所以在做界面的时候考虑了界面的色彩,并且添加了皮肤,界面上面的字体设置和windows窗口设置一样采用宋体,界面上的按钮不设置过多的按钮,仅设置有必要的按钮即可,界面设置大方。使用的时候有默认的IP地址、需要扫描的端口和线程数,如果需要扫描其他主机,只需要填写好要扫描的主机的IP地址,需要扫描的端口范围和线程数,单击命令提示按钮就可以开始扫描,扫描结果就会显示在中间的扫描结果显示区域,在扫描状态显示区就会显示是否扫描完毕。

4.2 界面设计图

本程序采用小窗口形式,外围大小为170mm*90mm,字体采用宋体五号,结果显示区域框架大小为160mm*45mm,底色为粉红,结果显示字幕为主机地址加开放端口。添加个性皮肤。其余地方设置按钮和扫描的主机地址、端口和线程数。设计的预计页面图形如图:

显示粉红底色 添加个性皮肤

图3 系统界面设计图

4.3 后台设计

本程序使用了为主要的Scanner类和Scan类。Scan类的作用是创建线程扫描端口,然后把结果显示到前台。Scanner类的作用是构造前台布局,调用Scan类添加事件处理,对输入进行错误判断,如果输入不在允许的范围之内则显示相关错误。

在本程序中用到了网络编程的两个类,下面介绍这两个类的常用方法。 InetSocketAddress类构造方法如下:

? InetSocketAddress(InetAddress addr, int port):根据 IP 地址和端口号创建套接字地址。

? InetSocketAddress(int port):创建套接字地址,其中 IP 地址为通配符地址,端口号为指定值。

? InetSocketAddress(String hostname, int port):根据主机名和端口号创建套接字地址。

Socket类常用方法如下:

? Socket():通过系统默认类型的 SocketImpl 创建未连接套接字

? Socket(InetAddress address, int port):创建一个流套接字并将其连接到指定 IP 地址的指定端口号。

? void bind(SocketAddress bindpoint):将套接字绑定到本地地址。 ? void close():关闭此套接字。

? void connect(SocketAddress endpoint):将此套接字连接到服务器。

? void connect(SocketAddress endpoint, int timeout):将此套接字连接到具有指定超时值的服务器。

? boolean isClosed():返回套接字的关闭状态。 ? boolean isConnected():返回套接字的连接状态。

本程序还调用其他的一些类和包,比如软件包 java.awt.color 、java.awt.event、io.IOException、Javax.Swing、jvnet.substance.*。

? java.awt.color包的的描述:提供用于颜色空间的类。它包含了基于国际色彩联盟 (ICC) 配置文件格式规范的颜色空间实现。它还包含了基于 ICC 配置文件格式规范的颜色配置文件。用来使界面更加具有色彩。 Result.setBackground(Color.PINK);//设置窗口为粉红

? java.awt.event 的描述:提供处理由 AWT 组件所激发的各类事件的接口和类。事件由事件源所激发,向事件源注册的事件侦听器可接收有关特定事件类型的通知。此包定义了事件和事件侦听器,以及事件侦听器适配器,它是让事件侦听器的编写过程更为轻松的便捷类。 在本程序中使用:

public void actionPerformed(ActionEvent e) {

String cmd = e.getActionCommand(); if(cmd.equals(\

………… }

? io.IOException包的描述:用来处理io的错误,不仅仅是文件读写,还包括很多stream的读写,而且throws是用来放在函数定义的函数体前函数名后的,表示这个函数将会在出现异常的书后会抛出io异常,所以在以后的程序中调用这个函数的时候就必须用try和catch来捕获异常,否则编译会报错,这主要涉及到java的安全机制。 本程序中使用如下: try { 数!\

minPort = Integer.parseInt(PortStart.getText()); maxPort = Integer.parseInt(PortEnd.getText()); threadNum = Integer.parseInt(ThreadNum.getText());

} catch (NumberFormatException e1) {

DLGError.setBounds(300, 280, 299, 120);

DLGINFO.setText(\错误的端口号或线程数!端口号和线程数必须为整

DLGINFO.setBounds(10, 20, 280, 20); OK.setBounds(110, 50, 60, 30); DLGError.setVisible(true); return;

………… }

? Javax.Swing集合描述:由所有Java图形用户界面(GUI)组件所构成,可运行在任一支持Java虚拟机(JVM)的本地平台上。由于这些组件全都是用Java语言编写的,因此它们可以提供比本地平台GUI组件更多的功能。(与抽象窗口工具箱对比)。Java Swing是Java Foundation Classes(JFC)的一部分。在Swing中,Sun开发了一个经过仔细设计的、灵活而强大的 GUI 工具包。Swing是在AWT组件基础上构建的。它所提供的功能要比AWT提供的更为广泛。它也是Java技术的一种标准配置。

Swing模型

一个Java GUI通常由顶层容器、中间容器以及多个原子组件组成。每个原子组件或容器都可能触发相应事件的产生。容器是一类能够在其中容纳其他组件的特殊组件。Swing的GUI组件类是按照类属层次以树状结构进行组织的。在这个树的最顶层,即树的根部,使一个最基本的容器类,被称为顶层容器。Swing 提供了三个通用的顶层容器类JFrame,JDialog和JApplet。JFrame提供了基于窗体的应用程序,JDialog提供对话框形式的界面,JApplet提供Java小应用程序的界面形式。在顶层容器下是中间容器,用于容纳其他的组件。通常窗格本身在显示界面中是看不到的。面板类Panel是一种中间容器,它的唯一作用是使组件更容易定位。顶层容器通过getContentPane()方法获取内部的一个内容窗格。

Swing包的组成:

? javax.swing:基本Swing包,包括Swing容器、组件及相关设置的类和接口。 ? javax.swing.border:包括与边界设计相关的类和接口。 ? javax.swing.colorchooser:与颜色选择相关的类和接口。 ? javax.swing.event:包括事件处理相关的类和接口。

? javax.swing.filechooser:包括对文件进行查看选取的相关类。 ? javax.swing.plaf:包括一些对外观样式操作的类和接口。 ? javax.swing.tree:包括对树形组件进行操作的类和接口。 常用Swing组件: ? 按钮:JButton ? 文本区:JTextArea ? 文本字段:JTextField 在本程序中使用如下:

// 设置主窗体位置和大小

mainFrame.setBounds(180, 200, 550, 300);

mainFrame.addWindowListener(new WindowAdapter(){

public void windowClosing(WindowEvent e){

System.exit(0);

// 设置扫描按钮和退出按钮

Start.setBounds(405, 232, 60, 30); Start.setActionCommand(\Start.addActionListener(this); Exit.setBounds(475, 232, 60, 30); Exit.setActionCommand(\Exit.addActionListener(this);

? jvnet.substance.*:目的是提供一个流行的外观(look & feel)。 //设置窗体皮肤

SubstanceAutumnLookAndFeel.setSkin(new FieldOfWheatSkin());

5 实现与测试 5.1 运行要求与环境

(1)性能要求

实时性好、可靠性强、不占用系统太多的内存和存储空间。 (2)设计约束

开发工具:J2SDK 1.6.0 Eclipse 运行环境:Windows 2000以上 能实现用户所定义的各项需求。

5.2 运行程序流程图

在Eclipse中右击,选择运行方式,JAVA应用程序 出现程序界面 填写IP地址,可填写任意的一个IP 设置开始端口大小,设置0~65535之间的端口号且必须为整数 设置结束口,设置0~65535之间的端口号且必须为整数,并且大于开始端口 设置进程数,0~200之间且必须为整数 点击扫描可以开始扫描 结果显示 是否继续扫描 否,点击退出 结束程序 图4 流程图

是,重新设置

5.3 运行界面

图5 运行界面图

未扫描状态

图6 运行界面未扫描状态图

正常扫描后状态

图7 运行界面正常扫描状态图

起始端口设置有误扫描开始后状态报错

图8 运行界面起始端口设置错误报错图

图9 运行界面起始端口设置错误报错图

结束端口设置有误扫描开始后状态报错

图10 运行界面结束端口设置错误报错图

线程数设置错误报错

图11 运行界面线程数设置错误报错图

6 设计总结

在此次课程设计中,遇到了一些问题,如:程序功能不能完全实现,对于面向对象的方法了解不够透彻,运用到实际的软件开发中存在着困难;对于Java语言,以前只学习到了一些最基本的知识,要在短时间内用Java语言来开发软件是一个较大的挑战;对于开发软件的流程不熟悉,适应起来比较慢,编写需求说明书和设计规格说明书时,自己感觉难以动手,这表明所学的知识不能灵活运用到实际中。

对于以上的问题,自己有清楚的认识,解决办法是需要大量阅读相关的书籍,多看些项目的源代码。对于书上以及网站上下载的资料中的Java实例必须理解,还有多跟精通JAVA语言的老师和同学请教和交流,取其精华。对于实际动手能力与软件开发的流程的适应,必须多进行实际的练习与操作,才能有所进步。

我自己感觉此次课程设计做得挺成功的,通过这一次实践编程,我学到了不少有关JAVA的实际编程的知识。

在这次设计开始的第一天开始,我就开始着手修改一个用JAVA编写的短线呈端口扫描的程序。我刚开始很自信自己能修改成功,但这一过程太不顺利。用了两天时间来修改那个JAVA程序,但调试的时候都没有成功。后来我请教一个班上成绩好的同学,在他的帮助下我不断的发现错误,并改正它们,功夫不负有心人人,我的程序最后运行成功了。

在这课程设计期间我的同学和老师帮助了我,有些东西是我们一起探讨,一起解决

方法的。当然在学习Java和设计程序的过程中还得到了杭志老师的辛勤指导,为我解答了不少的疑问。同时,在刘老师身上我们学到了很多实用的东西,在此表示衷心的感谢!同时,还要感谢帮助过我的其他同学!

这次课程设计令我感受很多。从拿到题目到改编JAVA程序;然后请教别人慢慢研究琢磨;从理论到实践;从失败到成功;忘不了我坐在电脑前苦苦思索,高温下熬夜地编程的疲惫;忘不了因沉迷于编程却耽误了吃饭时间而挨饿辛酸;忘不了……这其中了不少的东西,磨砺了我的意志;同时还巩固了以前所学的知识,学到了不少书本上没有的知识;学到了很多java编程知识,并学会了简单的使用eclipse来开发java程序的一些使用技巧这次课程设计是对我本学期所学的知识的检验,由此我发现了不少的问题。可以说它给了我一次自我评估的机会。通过设计让我知道了那些方面我还是有欠缺的,促使我花时间弥补。

临近考试,时间太紧迫,致使程序实现的功能在方法上也许不是很完美,但我以后会多向老师请教,自己也要加强对Java 的学习。努力进一步提高自己的编程水平。

此次的课程设计,对我来说撰写文档似乎是一个更大的挑战。撰写文档不仅要求我们要对自己程序非常熟悉:程序的总体框架,功能,如何实现,存在什么问题等,同时还要求我们有清晰的思维和准确的表达能力以及严密的逻辑性。因此,写完这篇文档对于我们自身来说自然是获益匪浅的。

参考文献

[1] Sharon Zakhour Scott Hommel等著. Java 语言导学.人民邮电出版社, 2008 [2] 耿祥义 编著. Java基础教程. 清华大学出版社, 2004

[3] Joe Wigglesworth Paula Lumby. Java程序设计高级主题. 北京大学出版社, 2004 [4] Y.Daniel Liang著,王镁等译.Java语言程序设计基础篇.2006 [5] 朱福喜等.Java项目设计与开发范例.电子工业出版社,2005

附件

/*基于多线程端口扫描程序源代码*/ import java.awt.Color; //类的调用 import java.awt.Container; import java.awt.Label; import java.awt.TextArea;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.IOException; import java.net.InetAddress;

import java.net.InetSocketAddress; import java.net.Socket;

import java.net.SocketAddress;

import java.net.UnknownHostException; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JTextField; import org.jvnet.substance.skin.*;

import org.jvnet.substance.skin.SubstanceAutumnLookAndFeel;

public class Scanner implements ActionListener{ // 创建主窗口

public static JFrame mainFrame = new JFrame(); public static Label labelIP = new Label(\主机IP\

public static Label labelPortStart = new Label(\起始端口:\ public static Label labelPortEnd = new Label(\结束端口:\ public static Label labelThread = new Label(\线程数:\ public static Label labelResult = new Label(\扫描结果:\ public static Label State = new Label(\扫描状态:\ public static Label Scanning = new Label(\未开始扫描\

public static JTextField hostName = new JTextField(\ public static JTextField PortStart = new JTextField(\ public static JTextField PortEnd = new JTextField(\ public static JTextField ThreadNum = new JTextField(\ // 文本区域,显示扫描结果

public static TextArea Result = new TextArea(); public static Label DLGINFO = new Label(\ public static JButton Start = new JButton(\扫描\ public static JButton Exit = new JButton(\退出\ // 错误提示对话框

public static JDialog DLGError = new JDialog(mainFrame, \错误\ public static JButton OK = new JButton(\确定\

public Scanner(){ //设置窗体皮肤

SubstanceAutumnLookAndFeel.setSkin(new FieldOfWheatSkin()); // 设置主窗体名称 mainFrame.setTitle(\多线程端口扫描器//吴虎\ // 设置主窗体位置和大小

mainFrame.setBounds(180, 200, 550, 300);

mainFrame.addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } });

// 设置错误提示框

Container dPanel = DLGError.getContentPane(); dPanel.setLayout(null); dPanel.add(DLGINFO); dPanel.add(OK);

OK.setActionCommand(\OK.addActionListener(this); // 在主窗体中添加其他组件 mainFrame.setLayout(null); mainFrame.setResizable(false); mainFrame.add(Start); mainFrame.add(Exit); mainFrame.add(labelIP); mainFrame.add(hostName); mainFrame.add(labelPortStart); mainFrame.add(labelPortEnd); mainFrame.add(PortStart); mainFrame.add(PortEnd); mainFrame.add(labelThread); mainFrame.add(ThreadNum); mainFrame.add(labelResult); mainFrame.add(Result); mainFrame.add(State); mainFrame.add(Scanning); // 设置扫描按钮和退出按钮 Start.setBounds(405, 232, 60, 30); Start.setActionCommand(\Start.addActionListener(this); Exit.setBounds(475, 232, 60, 30); Exit.setActionCommand(\Exit.addActionListener(this); labelIP.setBounds(17, 13, 50, 20); hostName.setBounds(67, 10, 92, 25);

hostName.setHorizontalAlignment(JTextField.CENTER);

labelPortStart.setBounds(162, 13, 60, 20); PortStart.setBounds(227, 10, 45, 25);

PortStart.setHorizontalAlignment(JTextField.CENTER);

labelPortEnd.setBounds(292, 13, 60, 20); PortEnd.setBounds(357, 10, 45, 25); PortEnd.setHorizontalAlignment(JTextField.CENTER); labelThread.setBounds(422, 13, 50, 20); ThreadNum.setBounds(477, 10, 45, 25); ThreadNum.setHorizontalAlignment(JTextField.CENTER); labelResult.setBounds(1, 45, 55, 20); Result.setBounds(1, 65, 542, 160); Result.setEditable(false); Result.setBackground(Color.PINK);//设置窗口为粉红 State.setBounds(17, 232, 60, 30); Scanning.setBounds(80, 232, 120, 30); mainFrame.setVisible(true); }

public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); //得到明明处理事件 if(cmd.equals(\ try { Scan.hostAddress = InetAddress.getByName(Scanner.hostName.getText()); } catch (UnknownHostException e1) { DLGError.setBounds(300, 280, 160, 110); DLGINFO.setText(\错误的IP地址/域名\ DLGINFO.setBounds(25, 15, 100, 20); OK.setBounds(45, 40, 60, 30); DLGError.setVisible(true); return ; } int minPort ; int maxPort ; int threadNum ; // 获取输入数据 try { minPort = Integer.parseInt(PortStart.getText()); maxPort = Integer.parseInt(PortEnd.getText()); threadNum = Integer.parseInt(ThreadNum.getText()); } catch (NumberFormatException e1) { DLGError.setBounds(300, 280, 299, 120); DLGINFO.setText(\错误的端口号或线程数!端口号和线程数必须为整数!\ DLGINFO.setBounds(10, 20, 280, 20); OK.setBounds(110, 50, 60, 30);

DLGError.setVisible(true); return; } // 输入信息错误处理 if((minPort < 0)||(maxPort > 65535)||(minPort > maxPort)){ DLGError.setBounds(300, 280, 295, 120); DLGINFO.setText(\最小端口必须是0-65535并且小于最大端口的整数\ DLGINFO.setBounds(10, 20, 280, 20); OK.setBounds(120, 50, 60, 30); DLGError.setVisible(true); return ; } if((threadNum > 200)|| (threadNum < 0)){ DLGError.setBounds(300, 280, 184, 120); DLGINFO.setText(\进程数必须是1-200中的整数\ DLGINFO.setBounds(10, 20, 200, 20); OK.setBounds(55, 50, 60, 30); DLGError.setVisible(true); return ; } Result.append(\正在扫描 \线程数:\ Scanning.setText(\开始扫描 ...\ Result.append(\开始端口 \结束端口 \ for(int i = minPort;i <= maxPort; ) { if((i + threadNum) <= maxPort) { new Scan(i, i + threadNum).start(); i += threadNum; } else { new Scan(i, maxPort).start(); i += threadNum; } } try { Thread.sleep(3000);//设置处理等待时间 } catch (InterruptedException e1) { e1.printStackTrace(); } Result.append(\扫描完成!\\n\ Scanning.setText(\扫描完成!\ } else if(cmd.equals(\ DLGError.dispose(); }

else if(cmd.equals(\ System.exit(1); } }

public static void main(String[] args) { new Scanner(); } }

class Scan extends Thread{ int maxPort, minPort;

public static InetAddress hostAddress;

Scan(int minPort, int maxPort){ this.minPort = minPort; this.maxPort = maxPort; }

public void run(){ // 扫描指定端口 for(int i = minPort;i < maxPort; i++){ Scanner.Scanning.setText(\正在扫描\端口\ try { // 根据主机名和端口号创建套接字地址。 SocketAddress sockaddr = new InetSocketAddress(hostAddress, i); Socket scans=new Socket(); int timeoutMs=50; // 将此套接字连接到具有指定超时值的服务器。 scans.connect(sockaddr, timeoutMs); // 关闭此套接字。 scans.close();

// 添加结果显示 Scanner.Result.append(\主机:\端口:\ switch(i){ case 20: Scanner.Result.append(\ case 21: Scanner.Result.append(\ case 23: Scanner.Result.append(\ case 25: Scanner.Result.append(\ case 38: Scanner.Result.append(\ case 53: Scanner.Result.append(\ case 79: Scanner.Result.append(\ case 80: Scanner.Result.append(\

}

}

}

case 110: Scanner.Result.append(\ case 161: Scanner.Result.append(\ case 443: Scanner.Result.append(\ case 1433: Scanner.Result.append(\ case 8000: Scanner.Result.append(\ } Scanner.Result.append(\开放\\n\} catch (IOException e) { }

本文来源:https://www.bwwdw.com/article/gy0x.html

Top