Java网络编程实现的简单端口扫描器示例
本文实例讲述了java网络编程实现的简单端口扫描器。分享给大家供大家参考,具体如下:
在计算机网络的学习中,不由得觉得这门课的零碎知识点异常之多,同时因为学习的课本是老外的教材——自顶向下方法,因此学习起来不免觉得吃力,但是从老外的教材里更能从一定高度理解计算机网络的知识体系,也是乐在其中,同时做英语的习题感觉也很有趣味,从各方面来说可以说是获益良多,认识了很多专业词汇。节课之后,便想做一个简单的端口扫描器,用的语言是java,因为实现界面很简单,同时也有封装好的socket类可以使用,主要思路如下:
在主程序界面里输入指定主机名或ip地址,按下start按钮,就可以扫描主机的常用端口是否打开。内部设置了常用端口号:21, 22, 23, 25, 26, 69, 80, 110, 143,443, 465, 995, 1080, 1158,1433, 1521, 2100, 3128, 3306, 3389,7001, 8080, 8081, 9080, 9090, 43958。也可以自行修改。程序实现原理就是利用java建立socket去连接目标ip的指定端口,如果能连接上就证明该端口开放。反之,若在超时之前都没有连接上,则该端口是关闭的,同时会产生异常。同时考虑到单线程操作效率较低,也利用了java可以多线程编程的特点,使用了多线程扫描目标主机的一个端口是否开放,因此最终显示结果中端口的排列顺序是随机的,且内部设定最多同时运行10个线程(可以根据实际情况更改)。
主要运用的网络知识就是套接字的使用。以及java内部的list容器,java的界面设计,界面布局,以及简单的泛型编程的用法。
主要代码如下:
import java.awt.borderlayout; import java.awt.color; import java.awt.font; import java.awt.gridlayout; import java.awt.event.actionevent; import java.awt.event.actionlistener; 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 java.util.arrays; import java.util.linkedlist; import java.util.list; import java.util.concurrent.executorservice; import java.util.concurrent.executors; import javax.swing.borderfactory; import javax.swing.jbutton; import javax.swing.jframe; import javax.swing.jlabel; import javax.swing.jpanel; import javax.swing.jscrollpane; import javax.swing.jtextarea; import javax.swing.jtextfield; public class scanport extends jframe { /** * 端口扫描启动主程序 */ private static final long serialversionuid = 1l; string str1 = " 常见端口有:"; string str2 = "ftp:21,22,telnet:23,smtp:25,http:80"; string str3 = "dns:53,tftp:69,snmp:161,162"; string str4 = "1158,1433,1521,2100,3128,26,69"; string str5 = "3306,3389,7001,8080,8081,110,143"; string str6 = "9080,9090,43958,443,465,995,1080"; jbutton jb1 = new jbutton("strat"); jtextarea jta = new jtextarea(); jscrollpane jsp = new jscrollpane(jta); jtextfield jtf = new jtextfield(17); string ip = "";//待扫描ip或域名 list <integer>portlist = new linkedlist<integer>();// 定义一个list容器表示扫描的团口的list集合 integer[] ports = new integer[] { 21, 22, 23, 25, 26, 53,69, 80, 110, 143, 443,465,69,161,162,135,995,1080,1158,1433,1521,2100, 3128, 3306, 3389, 7001, 8080, 8081, 9080, 9090, 43958 ,135,445,1025,1026,1027,1028,1055,5357}; // 常见端口集合 public scanport() { this.add(getpanel(), borderlayout.south); jsp.setborder(borderfactory.createetchedborder()); jsp.setbackground(color.cyan); this.add(jsp, borderlayout.center); this.add(getpanel2(), borderlayout.north); this.add(getpanel3(), borderlayout.west); this.setbounds(300, 60, 600, 600); this.setdefaultcloseoperation(jframe.exit_on_close); this.settitle("scanport"); jta.settabsize(4); jta.setfont(new font("标楷体", font.bold, 16)); jta.setlinewrap(true);// 激活自动换行功能 jta.setwrapstyleword(true);// 激活断行不断字功能 portlist.addall(arrays.aslist(ports)); //将ports中的值加入到set中,并去掉重复的 jb1.addactionlistener(new actionlistener() { @override public void actionperformed(actionevent e) { // todo auto-generated method stub ip = jta.gettext(); //ip为文本框内输入的字符串 scanports(ip, portlist, 10, 800); //超时时间设定为800,线程数设定为10 } }); this.setvisible(true); } /** * 多线程扫描目标主机指定list端口集合的开放情况 * * @param ip * 待扫描ip或域名 * @param portlist * 待扫描的端口的list集合 * @param threadnumber * 线程数 * @param timeout * 连接超时时间 * */ public void scanports(string ip, list<integer> portset,int threadnumber, int timeout) { executorservice threadpool = executors.newcachedthreadpool(); //线程池 for (int i = 0; i < threadnumber; i++) { //10个线程 加入到线程池里 scanmethod scanmethod2 = new scanmethod(ip, portset,threadnumber, i, timeout); threadpool.execute(scanmethod2); } threadpool.shutdown(); while (true) { if (threadpool.isterminated()) { system.out.println("扫描结束"); break; } try { thread.sleep(1000); } catch (interruptedexception e) { e.printstacktrace(); } }// end of while } /* * 扫描方式:针对一个待扫描的端口的list集合进行扫描 */ private class scanmethod implements runnable { private string ip; // 目标ip private list<integer> portlist; // 待扫描的端口的list集合 private int threadnumber, serial, timeout; // 线程数,这是第几个线程,超时时间 public scanmethod(string ip, list<integer> portlist, int threadnumber,int serial, int timeout) { this.ip = ip; this.portlist = portlist; this.threadnumber = threadnumber; this.serial = serial; this.timeout = timeout; } public void run() { int port = 0; integer[] ports = portlist.toarray(new integer[portlist.size()]); // list转数组 try { inetaddress address = inetaddress.getbyname(ip); //如果输入的是主机名,尝试获取ip地址 socket socket;//定义套接字 socketaddress socketaddress;//传递ip和端口 if (ports.length < 1) //若数组没有元素,返回,不执行 return; for (port = 0 + serial; port <= ports.length - 1; port += threadnumber) { //每次运行10个线程 socket = new socket(); //为对象分配内存空间 socketaddress = new inetsocketaddress(address, ports[port]); try { socket.connect(socketaddress, timeout); //对目标主机的指定端口进行连接,超时后连接失败 socket.close(); //关闭端口 system.out.println("端口 " + ports[port] + " :开放"); jta.append("端口 " + ports[port] + " :开放\n"); //在文本区域里更新消息 } catch (ioexception e) { system.out.println("端口 " + ports[port] + " :关闭"); jta.append("端口 " + ports[port] + " :关闭\n"); //产生异常表示端口关闭 } } } catch (unknownhostexception e) { e.printstacktrace(); } } //end of run() }//end of scanmethod public jpanel getpanel() { jpanel jp = new jpanel(); jp.add(jb1, borderlayout.center); jp.setborder(borderfactory.createraisedbevelborder()); jp.setbackground(color.lightgray); return jp; } public jpanel getpanel2() { jpanel jp = new jpanel(); jlabel jl = new jlabel(); jl.settext("请输入主机名或ip地址,将扫描该主机的常见端口号:"); jp.add(jl); jp.add(jtf); jp.setborder(borderfactory.createraisedbevelborder()); jp.setbackground(color.light_gray); return jp; } public jpanel getpanel3() { jlabel jl1 = new jlabel(str1); jlabel jl2 = new jlabel(str2); jlabel jl3 = new jlabel(str3); jlabel jl4 = new jlabel(str4); jlabel jl5 = new jlabel(str5); jlabel jl6 = new jlabel(str6); jpanel jp = new jpanel(); jp.setlayout(new gridlayout(6, 1)); jp.add(jl1); jp.add(jl2); jp.add(jl3); jp.add(jl4); jp.add(jl5); jp.add(jl6); jp.setborder(borderfactory.createetchedborder()); //蚀刻边框 return jp; } public static void main(string[] args) { new scanport(); } }
更多关于java相关内容感兴趣的读者可查看本站专题:《java网络编程技巧总结》、《java socket编程技巧总结》、《java文件与目录操作技巧汇总》、《java数据结构与算法教程》、《java操作dom节点技巧总结》和《java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。
上一篇: Java编程Nashorn实例代码