java扫描端口_用Java扫描端口的最快方式

如果每个65536端口需要200ms(在最坏的情况下,防火墙会阻塞所有的内容,这样您就可以为每一个端口启用超时),数学很简单:您需要13k秒或大约3个小时一半。

您有2(非排他)选项可以使其更快:

>减少你的超时

> paralellize你的代码

由于操作是I / O绑定(与CPU绑定相反 – 也就是说,您花费时间等待I / O,而不是为了完成一些巨大的计算),您可以使用许多线程。尝试从20开始。他们会分开3个半小时,所以最大预期时间约为10分钟。只要记住,这将对另一方施加压力,即扫描的主机将看到巨大的网络活动与“不合理”或“奇怪”的模式,使扫描非常容易检测。

最简单的方法(即最小化的变化)是使用ExecutorService和Future API:

public static Future portIsOpen(final ExecutorService es, final String ip, final int port, final int timeout) {

return es.submit(new Callable() {

@Override public Boolean call() {

try {

Socket socket = new Socket();

socket.connect(new InetSocketAddress(ip, port), timeout);

socket.close();

return true;

} catch (Exception ex) {

return false;

}

}

});

}

然后,您可以执行以下操作:

public static void main(final String... args) {

final ExecutorService es = Executors.newFixedThreadPool(20);

final String ip = "127.0.0.1";

final int timeout = 200;

final List> futures = new ArrayList<>();

for (int port = 1; port <= 65535; port++) {

futures.add(portIsOpen(es, ip, port, timeout));

}

es.shutdown();

int openPorts = 0;

for (final Future f : futures) {

if (f.get()) {

openPorts++;

}

}

System.out.println("There are " + openPorts + " open ports on host " + ip + " (probed with a timeout of " + timeout + "ms)");

}

如果您需要知道哪些端口是打开的(而不仅仅是上述示例中的端口),则需要将函数的返回类型更改为Future< SomethingElse>,其中SomethingElse将保存端口和结果的扫描,像:

public final class ScanResult {

private final int port;

private final boolean isOpen;

// constructor

// getters

}

然后,在第一个代码片段中将布尔值更改为ScanResult,并返回新的ScanResult(port,true)或新的ScanResult(port,false),而不是true或false

编辑:其实我刚刚注意到:在这种特殊情况下,您不需要ScanResult类来保存结果端口,并且仍然知道哪个端口是打开的。由于您将期货添加到已订购的列表中,并且稍后您将以与您添加的列表相同的顺序处理它们,您可以在每个迭代中增加一个计数器,以了解您正在处理哪个端口。但是,嘿,这只是要完整和准确。不要尝试这样做,这是可怕的,我很ash愧,我想到了这一点…使用ScanResult对象更干净,代码更容易阅读和维护,并允许您,稍后,例如,使用CompletionService来改进扫描仪。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
public static JFrame main=new JFrame("JAVA端口扫描器"); //显示扫描结果 public static JTextArea Result=new JTextArea("",4,40); //滚动条面板 public static JScrollPane resultPane = new JScrollPane(Result,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); //输入主机名文本框 public static JTextField hostname=new JTextField("localhost",8); //输入ip地址前3位的输入框 public static JTextField fromip1=new JTextField("0",3); //输入ip地址4~6位的输入框 public static JTextField fromip2=new JTextField("0",3); //输入ip地址7~9位的输入框 public static JTextField fromip3=new JTextField("0",3); //输入起始ip地址最后4位的输入框 public static JTextField fromip4=new JTextField("0",3); //输入目标ip地址最后4位的输入框 public static JTextField toip=new JTextField("0",3); //输入最小端口的输入框 public static JTextField minPort=new JTextField("0",4); //输入最大端口的输入框 public static JTextField maxPort=new JTextField("1000",4); //输入最大线程数量的输入框 public static JTextField maxThread=new JTextField("100",3); //错误提示框 public static JDialog DLGError=new JDialog(main,"错误!"); public static JLabel DLGINFO=new JLabel(""); public static JLabel type=new JLabel("请选择:"); //扫描类型 public static JRadioButton radioIp = new JRadioButton("IP地址:"); public static JRadioButton radioHost = new JRadioButton("主机名:",true); //单选框组 public static ButtonGroup group = new ButtonGroup(); public static JLabel P1=new JLabel("端口范围:"); public static JLabel P2=new JLabel("~"); public static JLabel P3=new JLabel("~"); public static JLabel Pdot1 = new JLabel("."); public static JLabel Pdot2 = new JLabel("."); public static JLabel Pdot3 = new JLabel("."); public static JLabel TNUM=new JLabel("线程数:"); public static JLabel RST=new JLabel("扫描结果: "); public static JLabel con=new JLabel(" "); //定义按钮 public static JButton OK = new JButton("确定"); public static JButton Submit = new JButton("开始扫描"); public static JButton Cancel = new JButton("退出"); public static JButton saveButton = new JButton("保存扫描结果"); //菜单栏 public static JMenuBar myBar = new JMenuBar(); public static JMenu myMenu = new JMenu("文件(F)"); public static JMenuItem saveItem = new JMenuItem("保存扫描结果(S)"); public static JMenuItem exitItem = new JMenuItem("退出(Q)"); public static JMenu myMenu2 = new JMenu("帮助"); public static JMenuItem helpItem = new JMenuItem("阅读"); public static void main(String[] args){ main.setSize(500,400); main.setLocation(300,300); main.setResizable(false); main.setLayout(new GridBagLayout()); main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); DLGError.setSize(300,100); DLGError.setLocation(400,400); //添加“菜单栏” myMenu.add(saveItem); myMenu.add(exitItem); myMenu2.add(helpItem); myBar.add(myMenu); myBar.add(myMenu2); main.setJMenuBar(myBar); //设置热键 myMenu.setMnemonic('F'); saveItem.setMnemonic ('S'); //为“另存为”组件设置快捷键为ctrl+s saveItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_S,InputEvent.CTRL_MASK)); exitItem.setMnemonic('Q'); exitItem.setAccelerator (KeyStroke.getKeyStroke (KeyEvent.VK_E,InputEvent.CTRL_MASK)); //采用表格包型布局 Container mPanel = main.getContentPane(); GridBagConstraints c = new GridBagConstraints(); c.insets = new Insets(10,0,0,10); c.gridx = 0; c.gridy = 0; c.gridwidth = 10; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(type,c); group.add(radioIp); group.add(radioHost); c.gridx = 0; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(radioIp,c); c.gridx = 1; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip1,c); c.gridx = 2; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(Pdot1,c); c.gridx = 3; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip2,c); c.gridx = 4; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(Pdot2,c); c.gridx = 5; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip3,c); c.gridx = 6; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(Pdot3,c); c.gridx = 7; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(fromip4,c); c.gridx = 8; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(P2,c); c.gridx = 9; c.gridy = 1; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(toip,c); c.gridx = 0; c.gridy = 2; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(radioHost,c); c.gridx = 1; c.gridy = 2; c.gridwidth = 3; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(hostname,c); c.gridx = 0; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(P1,c); c.gridx = 1; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(minPort,c); c.gridx = 2; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(P3,c); c.gridx = 3; c.gridy = 3; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(maxPort,c); c.gridx = 0; c.gridy = 4; c.gridwidth = 1; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(TNUM,c); c.gridx = 1; c.gridy = 4; c.gridwidth = 3; c.fill = GridBagConstraints.BOTH; c.anchor = GridBagConstraints.CENTER; mPanel.add(maxThread,c);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值