基于多线程的端口扫描程序.docx
《基于多线程的端口扫描程序.docx》由会员分享,可在线阅读,更多相关《基于多线程的端口扫描程序.docx(25页珍藏版)》请在冰豆网上搜索。
基于多线程的端口扫描程序
计算机网络课程课程设计任务书
学院
计算机与信息工程
专业
网络工程
课程名称
计算机网络
题目
基于多线程的端口扫描程序
完成期限
自2014年6月9日至2014年6月16日共1周
内
容
及
任
务
一、项目的目的
掌握Socket的基本功能,锻炼Java高级编程的能力。
二、项目任务的主要内容和要求
使用Socket实现简单的端口扫描功能。
分别针对TCP和UDP,采用多线程技术实现端口扫描,给出扫描结果。
实现本程序需要了解网络基础知识、网络安全基础知识,掌握C/S结构的工作特点,掌握高级语言及网络编程知识,可以选择VisualC++、C或Java等语言实现。
三、项目设计(研究)思路
设计信息检测模块检测IP地址,再采取匹配过滤原则筛选进程端口,利用Socket实现简单的端口扫描功能,最后检测信息是否符合要求。
四、具体成果形式和要求
(1)给出程序的流程图;
(2)给出程序源码;
(3)给出程序的部分运行测试结果。
进
度
安
排
起止日期
工作内容
6月13日至6月14日
分析题目,搜索相关资料,整理相关资料,确定程序分工
6月15日至6月17日
编写程序代码,调试改进程序。
6月18日至6月19日
编写课程设计报告。
主
要
参
考
资
料
[1]赵生慧.Java面向对象程序设计.北京:
中国水利水电出版社,2010。
[2]谢希仁.计算机网络(第五版).北京:
电子工业出版社,2011。
[3]杨静宇.Java程序设计与应用开发(第2版)[M].北京:
清华大学出版社,2009。
指导教师
意见
(签字):
×年×月×日
系(教研室)主任意见
(签字):
×年×月×日
计算机网络设计说明书
学院名称:
计算机与信息工程学院
班级名称:
网络工程122班
学生姓名:
学号:
题目:
基于多线程的端口扫描程序
指导教师
姓名:
起止日期:
2015年6月13日至2015年6月20日
一、选题背景
随着互联网的飞速发展,网络入侵行为日益严重,网络安全成为人们关注的焦点。
端口扫描技术是网络安全扫描技术的重要技术之一。
对目标系统进行端口扫描,是网络系统入侵者进入目标系统的第一步。
网络安全探测在网络安全中起着主动防御的作用,占有非常重要的地位。
网络安全探测的所有功能都是建立在端口扫描的基础上,所以对端口扫描技术的研究有着非常重要的现实意义。
现实世界中的很多过程都具有多条线索同时动作的特性。
Java语言的一大特性就是内置对多线程的支持。
多线程是指同时存在几个执行体,按几条不同的执行线索共同工作的情况,它使得编程人员可以很方便地开发出具有多线程功能、能同时处理多个任务的功能强大的应用程序。
端口是由计算机的通信协议TCP/IP协议定义的。
其中规定,有IP地址和端口号作为套接字,它代表TCP连接的一个连接端,一般称为Socket。
具体来说,就是用[IP:
端口]来定位一台主机的进程。
可见端口与进程是一一对应的,如果某个进程正在等待连接,称之为该进程正在监听,那么就会出现与它相对应的端口。
由此可见,通过扫描端口,就可以判断出目标计算机有哪些通信进程正在等待连接。
利用TCP connect扫描原理,扫描主机通过TCP/IP协议的三次握手与目标主机的指定端口建立一次完整的连接,如果目标主机该端口有回复,则说明该端口开放。
利用多线程技术实现了对一目标IP进行设定数目的端口扫描,对多IP段的特定端口进行扫描。
二、方案设计
多线程端口扫描器是实现计算机的端口的扫描,只要在在前台设置好所要扫描的IP、起始端口、结束端口以及所要用到的线程数,点击扫描,就可以扫描到所输入IP地址主机的开放端口,并显示在主窗体中;点击退出,则可以退出该程序。
IP设置应为所在主机的IP地址,起始端口和结束端口应为0~65535之间的一个数,且起始端口应小于结束端口的大小。
线程数为0~200之间的一个数。
点击开始后就会运行,直到扫描完毕显示出开放端口,如果没有开放端口,则只显示扫描完毕。
本系统要实现的功能:
①端口扫描功能:
扫描开放的端口,并将扫描到的开放端口号送到前台。
②图像显示功能:
显示图形界面,以及显示扫描结果。
③多线程功能:
当客户端要求与服务器端建立连接时,服务器端就将用到多线程功能,为每一个建立起来的连接创建一个线程。
④异常抛出功能:
对于明显的数据错误,能提示出错误的类型并阻止程序的运行。
流程图:
三、详细设计
本程序是由3模块组成的:
图形界面,按钮的监听及数据检验,端口扫描
(1)图形用户界面是软件产品和用户交互的接口,是软件产品中用户直接可以看到并直接操作的部分。
publicstaticJFramemain=newJFrame("基于JAVA的多线程TCP端口扫描程序\\李梦然");
publicstaticJTextAreaResult=newJTextArea("",4,44);
publicstaticJTextFieldhostname=newJTextField("localhost",8);
publicstaticJTextFieldminPort=newJTextField("0",4);
publicstaticJTextFieldmaxPort=newJTextField("1000",4);
publicstaticJTextFieldmaxThread=newJTextField("100",3);
publicstaticJDialogDLGError=newJDialog(main,"错误!
");
publicstaticLabelDLGINFO=newLabel("");
publicstaticLabelstatus=newLabel("扫描状态:
未开始");
publicScanner()
{
main.setSize(500,220);
main.setLocation(350,300);
main.setResizable(false);
DLGError.setSize(300,100);
DLGError.setLocation(450,400);
Result.setBackground(Color.pink);
JPanelmainPanel=newJPanel();
LabelH=newLabel("ip:
");
LabelP1=newLabel("端口范围:
");
LabelP2=newLabel("—");
LabelTNUM=newLabel("线程数:
");
LabelRST=newLabel("扫描结果:
");
Result.setLineWrap(true);
Result.setEditable(false);
JButtonOK=newJButton("确定");
JButtonSubmit=newJButton("确定");
JButtonCancel=newJButton("取消");
ContainermPanel=main.getContentPane();
ContainerdPanel=DLGError.getContentPane();
mPanel.setLayout(newFlowLayout(FlowLayout.LEFT));
dPanel.setLayout(newFlowLayout(FlowLayout.CENTER));
mPanel.add(H);
mPanel.add(hostname);
mPanel.add(P1);
mPanel.add(minPort);
mPanel.add(P2);
mPanel.add(maxPort);
mPanel.add(TNUM);
mPanel.add(maxThread);
mPanel.add(RST);mPanel.add(Result);
mPanel.add(status);
mPanel.add(Submit);
mPanel.add(Cancel);
dPanel.add(DLGINFO);
dPanel.add(OK);
main.setVisible(true);
Submit.addActionListener(newSubmitAction());
Cancel.addActionListener(newCancleAction());
OK.addActionListener(newOKAction());
(2)按钮监听是整个程序的时间驱动设计部分。
并且显示运行结果。
数据处理是对用户输入的数据进行检验是否错误,来进行报错处理。
classCancleActionimplementsActionListener
{
publicvoidactionPerformed(ActionEvente)
{
System.exit
(1);
}
}
classSubmitActionimplementsActionListener
{
publicvoidactionPerformed(ActionEventa)
{
intmin;
intmax;
intnum;
try
{
min=Integer.parseInt(Scanner.minPort.getText());
max=Integer.parseInt(Scanner.maxPort.getText());
num=Integer.parseInt(Scanner.maxThread.getText());
}
catch(NumberFormatExceptione)
{
Scanner.DLGINFO.setText("错误的端口号或线程数!
端口号和线程数必须为整数!
");
Scanner.DLGError.setVisible(true);
Scanner.status.setText("扫描状态:
未开始");
return;
}
try
{
Saomiao.hostAddress=InetAddress.getByName(Scanner.hostname.getText());
}
catch(UnknownHostExceptione)
{
Scanner.DLGINFO.setText("错误的IP地址/域名或地址不可达!
");
Scanner.DLGError.setVisible(true);
Scanner.status.setText("扫描状态:
未开始");
return;
}
if(min<0||min>65535||min>max)
{
Scanner.DLGINFO.setText("最小端口必须是0-65535并且小于最大端口的整数!
");
Scanner.DLGError.setVisible(true);
return;
}
else
Saomiao.minport=min;
if(max<0||max>65535||max{
Scanner.DLGINFO.setText("最大端口必须是0-65535并且大于最小端口的整数!
");
Scanner.DLGError.setVisible(true);
Scanner.status.setText("扫描状态:
未开始");
return;
}
else
Saomiao.maxport=max;
if(num<1||num>200)
{
Scanner.DLGINFO.setText("线程数为1-200的整数!
");
Scanner.DLGError.setVisible(true);
Scanner.status.setText("扫描状态:
未开始");
return;
}
Scanner.Result.setText("");
Scanner.Result.append("正在扫描"+Scanner.hostname.getText()+"线程数"+Scanner.maxThread.getText()+"\n");
Scanner.Result.append("开放端口:
");
for(inti=0;i{
newSaomiao(i).start();
}
}
}
classOKActionimplementsActionListener
{
publicvoidactionPerformed(ActionEvente)
{
Scanner.DLGError.dispose();
}
}
(3)端口扫描程序主要运用Socket编程。
其工作过程包含以下四个基本步骤:
创建通信双方的socket链接,即分别为服务器和客户端创建Socket对象,建立Socket连接;打开连接到Socket的输入流和输出流;按照一定的协议对Socket进行读/写操作;关闭连接。
staticclassSaomiaoextendsThread
{
publicstaticInetAddresshostAddress;
publicstaticintminport;
publicstaticintmaxport;
privateintthreadnum;
publicSaomiao(intthreadnum)
{
this.threadnum=threadnum;
}
publicvoidrun()
{
inti;
SockettheTCPsocket;
for(i=minport+threadnum;i{
Scanner.status.setText("扫描状态:
正在扫描"+i+"端口");
try
{
theTCPsocket=newSocket(hostAddress,i);
theTCPsocket.close();
Scanner.Result.append(""+i);
switch(i)
{
case21:
Scanner.Result.append("(FTP)");
break;
case23:
Scanner.Result.append("(TELNET)");
break;
case25:
Scanner.Result.append("(SMTP)");
break;
case80:
Scanner.Result.append("(HTTP)");
break;
case110:
Scanner.Result.append("(POP)");
break;
case139:
Scanner.Result.append("(netBIOS)");
break;
case161:
Scanner.Result.append("(SNMP)");
break;
case443:
Scanner.Result.append("(HTTPS)");
break;
case1433:
Scanner.Result.append("(SQL)");
break;
case8000:
Scanner.Result.append("(OICQ)");
break;
}
Scanner.Result.append(",");
}catch(IOExceptione){}
}
if(i==maxport)
{
Scanner.Result.append("\n"+"扫描完成...");
Scanner.status.setText("扫描状态:
完成!
");
}
}
}
四、结果分析
运行要求与环境
(1)性能要求
实时性好、可靠性强、不占用系统太多的内存和存储空间。
(2)设计约束
开发工具:
J2SDK1.6.0Eclipse
运行环境:
Windows8
能实现用户所定义的各项需求。
运行程序流程图:
(1)Eclipse界面:
(2)程序初始界面:
(3)程序运行结果:
(4)IP地址报错:
(5)端口范围报错:
(6)线程数报错:
五、结论
在此次课程设计中,遇到了一些问题,如:
程序功能不能完全实现,对于面向对象的方法了解不够透彻,运用到实际的软件开发中存在着困难;对于Java语言,以前只学习到了一些最基本的知识,要在短时间内用Java语言来开发软件是一个较大的挑战;对于开发软件的流程不熟悉,适应起来比较慢,编写需求说明书和设计规格说明书时,自己感觉难以动手,这表明所学的知识不能灵活运用到实际中。
对于以上的问题,自己有清楚的认识,解决办法是需要大量阅读相关的书籍,多看些项目的源代码。
对于书上以及网站上下载的资料中的Java实例必须理解,还有多跟精通Java语言的老师和同学请教和交流,取其精华。
对于实际动手能力与软件开发的流程的适应,必须多进行实际的练习与操作,才能有所进步。
这次课程设计令我感受很多。
从拿到题目到编写Java程序;然后请教别人慢慢研究琢磨;从理论到实践;从失败到成功;忘不了我坐在电脑前苦苦思索,高温下熬夜地编程的疲惫;忘不了因沉迷于编程却耽误了吃饭时间而挨饿辛酸;忘不了……这其中了不少的东西,磨砺了我的意志;同时还巩固了以前所学的知识,学到了不少书本上没有的知识;学到了很多Java编程知识,并学会了简单的使用Eclipse来开发Java程序的一些使用技巧这次课程设计是对我本学期所学的知识的检验,由此我发现了不少的问题。
可以说它给了我一次自我评估的机会。
通过设计让我知道了那些方面我还是有欠缺的,促使我花时间弥补。
临近考试,时间太紧迫,致使程序实现的功能在方法上也许不是很完美,但我以后会多向老师请教,自己也要加强对Java的学习。
努力进一步提高自己的编程水平。
此次的课程设计,对我来说撰写文档似乎是一个更大的挑战。
撰写文档不仅要求我们要对自己程序非常熟悉:
程序的总体框架,功能,如何实现,存在什么问题等,同时还要求我们有清晰的思维和准确的表达能力以及严密的逻辑性。
因此,写完这篇文档对于我们自身来说自然是获益匪浅的。
参考文献
[1]赵生慧.Java面向对象程序设计.北京:
中国水利水电出版社,2010。
[2]谢希仁.计算机网络(第五版).北京:
电子工业出版社,2011。
[3]杨静宇.Java程序设计与应用开发(第2版)[M].北京:
清华大学出版社,2009。
学生签名:
填表日期:
年月日
附件
/*基于多线程端口扫描程序源代码*/
import.*;
importjava.io.*;
importjava.awt.*;
importjava.awt.event.*;
importjavax.swing.*;
publicclassScanner
{
publicstaticJFramemain=newJFrame("基于JAVA的多线程TCP端口扫描程序\\李梦然");
publicstaticJTextAreaResult=newJTextArea("",4,44);
publicstaticJTextFieldhostname=newJTextField("localhost",8);
publicstaticJTextFieldminPort=newJTextField("0",4);
publicstaticJTextFieldmaxPort=newJTextField("1000",4);
publicstaticJTextFieldmaxThread=newJTextField("100",3);
publicstaticJDialogDLGError=newJDialog(main,"错误!
");
publicstaticLabelDLGINFO=newLabel("");
publicstaticLabelstatus=newLabel("扫描状态:
未开始");
publicScanner()
{
main.setSize(500,220);
main.setLocation(350,300);
main.setResizable(false);
DLGError.setSize(300,100);
DLGError.setLocation(450,400);
Result.setBackground(Color.pink);
JPanelmainPanel=newJPanel();
LabelH=newLabel("ip:
");
LabelP1=newLabel("端口范围:
");
LabelP2=newLabel("—");
LabelTNUM=newLabel("线程数:
");
LabelRST=newLabel("扫描结果:
");
Result.setLineWrap(true);
Result.setEditable(false);
JButtonOK=newJButton("确定");
JButtonSubmit=newJButton