admin管理员组

文章数量:1530077

2024年3月23日发(作者:)

实验5:端口扫描器的设计与实现

姓名: 学号:

专业年级:

(一)实验目的和内容:

目的:加深对TCP的理解,学习端口扫描技术和原理,熟悉socket编程。

内容:实现一个扫描器,使用TCP connect进行端口扫描,并对扫描结果进行

记录。

(二)课程设计要求:

Windows或Linux环境下,程序在单机上运行;

使用端口扫描器对一台主机进行扫描,并显示出结果;

编程语言不限;提供友好的用户界面。

(三)端口扫描技术:

“端口” 是专门为计算机通信而设计的,它不是硬件,不同于计算机中的“插

槽”,可以说是个“软插槽”。

“端口” 是由计算机的通信协议TCP/IP协议定义的。其中规定,用IP地址

和端口作为套接字,它代表TCP连接的一个连接端,一般称为Socket。

具体来说,就是用[IP:端口]来定位一台主机中的进程。计算机就像一座

大楼,这个大楼有好多入口(端口),进到不同的入口中就可以找到不同的公

司(进程)。

端口与进程是一一对应的,入侵者通过扫描端口,便可以判断出目标计算

机有哪些通信进程正在等待连接。

(四)扫描端口的目的:

端口扫描是入侵者搜集信息的几种常用手法之一,也正是这一过程最容易使

入侵者暴露自己的身份和意图。

• 判断目标主机上开放了哪些服务;

• 判断目标主机的操作系统。

如果入侵者掌握了目标主机开放了哪些服务,运行何种操作系统,他们就能

够使用相应的手段实现入侵。

(五)端口的分类:

端口是一个16 bit的地址,用端口号进行标识不同的作用。端口一般分为两

类。

• 熟知端口号(公认端口号):由因特网指派名字和号码公司ICANN负责分

配给一些常用的应用层程序固定使用的熟知端口,其数值一般为0~1023。

• 一般端口号:用来随时分配给请求通信的客户进程。

(六)扫描原理的基础知识:

TCP/IP模型四层结构

TCP与UDP协议

TCP报文结构

TCP连接和释放过程

(七)TCP/IP模型四层结构:

(八)TCP与UDP协议:

Internet的网络通信大多是建立在这两个协议之上的,各个主机遵循着

TCP/IP协议封装数据包进行通信。

传输控制协议TCP(Transmission Control Protocol):TCP提供可靠的、面

向连接的运输服务,用于高可靠性数据的传输。TCP具有完善的错误检测与恢复、

顺序控制和流量控制等功能。注重可靠性的场合一般使用TCP协议,例如FTP、

Telnet。

用户数据报协议UDP(User Datagram Protocol):UDP在传送数据之前不需

要先建立连接。远地主机的运输层在收到UDP数据报后,不需要给出任何确认。

广泛应用于只需一次的C/S模式的请求-应答查询,或者要求提供高效率数据传

输的场合。注重实时性、传输率、吞吐量的场合一般使用UDP,如QQ。

(九)TCP connect扫描:

实现原理:通过调用socket函数connect()连接到目标计算机上,完成一次

完整的三次握手过程。如果端口处于侦听状态,那么connect()就能成功返回。

否则,这个端口不可用,即没有提供服务。

优点:稳定可靠,不需要特殊的权限。

缺点:扫描方式不隐蔽,服务器日志会记录下大量密集的连接和错误记录 ,

并容易被防火墙发现和屏蔽。

实验设计流程:

1. 原理概述

通过调用socket函数connect()连接到目标计算机上,完成一次完整的三

次握手过程。如果端口处于侦听状态,那么connect()就能成功返回。否则,这

个端口不可用,即没有提供服务。

2. 运行环境

本扫描软件用java语言开发,可稳定的运行在linux和windows环境下。

3.基本设计思路

用户界面:使用java里面的swing包来开发用户界面;

端口扫描:使用socket函数connect()连接目标计算机来判定是否目标计

算机开放了要测试的端口;

4..功能模块设计

本软件只有一个功能模块,就是是指定主机的端口扫描。

5.程序流程及主要算法

核心算法是TCP 的连接函数

Socket socket = new Socket(host,port); //建立套接字

if(ected()) //判断端口号是否开放

{

("port: "+port+" is open !n");

(f(port));

.............

6.程序使用说明

(1)运行程序

(2)输入IP地址、开始端口号、技术端口号,点击“开始扫描”

(3)可以看到开放端口号与未开放端口号,得到如下结果:

7.程序分析与总结

本程序使用java语言开发,可以稳定的运行在windows和linux系统下,不

过程序是单线程的扫描起来比较慢。

附录 - 源程序代码文件

import ;

import ;

import ;

import Event;

import Listener;

import ption;

import dress;

import ;

import nHostException;

import ist;

import or;

import ;

import n;

import ;

import ;

import nPane;

import lPane;

import rea;

import ield;

public class PortScanWind implements ActionListener,Runnable

{

private JFrame wind; //构建窗口

private JTextField jtf, jtf2, jtf3; //3个文本

private JLabel[] label = new JLabel[6]; //6个标签

private int startPort, endPort; //端口

private InetAddress host; //取得本机IP

private JButton btn,stop;// 点击事件

private JTextArea jta,jta2; //2个显示纯文本的多行区域

private JScrollPane jspane,jspane2; //滚动条

private Thread ps;

private List list;

public PortScanWind() {

wind = new JFrame("端口扫描程序");

e(400, 600);

jta = new JTextArea(10,10);

jta2 = new JTextArea(10,10);

jspane = new JScrollPane(jta);

jspane2 = new JScrollPane(jta2);//两个竖直滚动条

list = new ArrayList();

jtf = new JTextField(20);

jtf2 = new JTextField(20);

jtf3 = new JTextField(20);//20个字符

label[0] = new JLabel("端口扫描程序");

label[1] = new JLabel("主机地址:");

label[2] = new JLabel("开始端口号:");

label[3] = new JLabel("结束端口号:");

label[4] = new JLabel("开放端口:");

label[5] = new JLabel("未开放端口:");

btn = new JButton("开始扫描");

stop = new JButton("停止扫描");

ps =new Thread(this);

label[0].setBounds(100, 35, 400, 40);//(X,Y,宽,高) 端口扫描程序

label[0].setFont(new Font("微软雅黑", , 32));

label[0].setForeground();

label[1].setBounds(30, 100, 300, 30);//主机地址:

nds(150, 100, 200, 30);

label[1].setForeground(); //蓝色

label[2].setBounds(30, 150, 300, 30);//开始端口号:

nds(150, 150, 200, 30);

label[2].setForeground();

label[3].setBounds(30, 200, 300, 30);//结束端口号:

nds(150, 200, 200, 30);

label[3].setForeground();

label[4].setBounds(30,280,200,30);//开放端口:

label[5].setBounds(220,280,200,30);//未开放端口:

label[4].setForeground();

label[5].setForeground();

nds(90, 250, 100, 30);//开始扫描

ionListener(this);

nds(220,250,100,30);//停止扫描

ionListener(this);

bled(false);

nds(30, 310, 150,230);//结果显示

nds(220,310,150,230);

}

out(null);

for(int i=0;i<6;i++)

{

(label[i]);

}

(jtf);

(jtf2);

(jtf3);

(btn);

(jspane);

(stop);

(jspane2);

izable(false);

ationRelativeTo(null);

aultCloseOperation(_ON_CLOSE);

ible(true);

public static void main(String[] args) {

new PortScanWind();

}

@SuppressWarnings("deprecation")

@Override

public void actionPerformed(ActionEvent e) {

if(rce()==btn)

{

t("");

t("");

bled(true);

//获取用户输入的地址和端口号

String ip=t();

String sport = t();

String eport = t();

//对用户的输入进行验证

if(("")||ip==null)

{

ssageDialog(wind, "请输入主机地址!");

return ;

}else

{

try {

host =ame(ip);

} catch (UnknownHostException e1) {

ssageDialog(wind, "请输入有效的主机

地址!");

n("host初始化失败");

return;

//tackTrace();

}

}

if(("")||sport==null)

{

ssageDialog(wind, "请输入开始扫描的端口

号!");

return ;

}else

{

startPort = nt(sport);

}

if(("")||eport==null)

{

ssageDialog(wind, "请输入结束扫描的端口

号!");

return ;

}else

{

endPort = nt(eport);

if(endPort

{

ssageDialog(wind, "您输入的结束端口

号太小,请重新输入!");

return ;

}

}

//("开始扫描端口了。。。。。。。。。。。n");

ssageDialog(wind, "开始扫描!");

bled(false);//不可按

table(false);

table(false);

table(false);

if(ps!=null)

{

}

();

}else

{

ps=new Thread(this);

();

}

}

if(rce()==stop)

{

bled(true);

table(true);

table(true);

table(true);

bled(false);

();

ps=null;

All(list); //清空保存的端口数据

}

@Override

public void run() {

int port=startPort; //正在扫描的端口号

while(port <= endPort){ //循环扫描指定范围的端口

try {

Socket socket = new Socket(host,port); //建立套接字

if(ected()) //判断端口号是否开放

{

("port: "+port+" is open !n");

(f(port));

int height=8;

Point p = new Point();

ation(0,eCount()*height);

wport().setViewPosition(p);

n("host:"+host+" port: "+port+"is open !n");

}

} catch (UnknownHostException e) {

tackTrace();

} catch (IOException e) {

}

("port: "+port+" is not open !n");

int height=10;

Point p = new Point();

ation(0,eCount()*height);

wport().setViewPosition(p);

n("host:"+host+" port: "+port+" is not open !n");

}

port+=1;

}

if(()>0)

{

("扫描结果:共"+()+"个端口开放.n");

("分别是:n");

Iterator iterator=or(); //获取迭代器

while(t()) //遍历结果,并且输出结果

{

(()+"n");

}

}

}

本文标签: 端口端口号扫描使用端口扫描