Java网络编程实现的简单端口扫描器示例

时间:2021-05-02

本文实例讲述了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的界面设计,界面布局,以及简单的泛型编程的用法。

主要代码如下:

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 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程序设计有所帮助。

原文链接:https://blog.csdn.net/wangbowj123/article/details/76473065

声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。

相关文章