0 java for-loop freeze port-scanning
下面的代码是我用来创建端口扫描程序的,但是,当我点击"扫描"它执行但gui冻结直到它完成扫描,是否有任何可能的方法允许它在扫描时执行其他操作?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class PortScannerGUI extends JFrame implements ActionListener
{
JPanel Panel = new JPanel(null);
JTextField Field = new JTextField();
JButton Button = new JButton();
JTextArea Area = new JTextArea();
JButton limit = new JButton("limit");
public PortScannerGUI()
{
super();
setSize(350, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
LoadUI();
}
public void LoadUI()
{
Area.setBounds(20, 50, 310, 310);
Area.setBorder(BorderFactory.createLineBorder(Color.BLUE));
Area.setEditable(false);
Field.setBounds(20, 10, 200, 35);
Button.setBounds(230, 10,100, 35);
Button.setText("Scan");
Button.addActionListener(this);
Panel.add(Field);
Panel.add(Area);
Panel.add(Button);
add(Panel);
setVisible(true);
}
public static void main(String[] args)
{
PortScannerGUI Main = new PortScannerGUI();
}
@Override
public void actionPerformed(ActionEvent arg0)
{
Thread Runner = new Thread();
Runner.start();
int j=0;
String str = Field.getText();
for(int i=1;i<str.length();i++)
{
if(str.substring(i-1, i).equals("."))
{
j++;
}
}
if(!str.equals("") || j==4 || j==6)
{
try
{
InetAddress IP = InetAddress.getByName(str);
PortScanner P = new PortScanner(IP);
}
catch (Exception e){}
}
else
{
JOptionPane.showMessageDialog(null, "Not an IP address");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个顶部代码是GUI部分的代码,下面是实际扫描端口的代码.
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
public class PortScanner
{
public PortScanner(InetAddress iA)
{
for (int port = 1; port <= 65535; port++)
{
try
{
Socket s = new Socket(iA, port);
System.out.println("Port " + port + " is open");
s.close();
}
catch(IOException e)
{
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是在Swing事件线程(EDT或事件调度线程)中执行长时间运行的过程的典型示例,因此冻结此线程使GUI无法运行.我们看到这种事情一次又一次地发布,并且解决方案是相同的并且相对简单:在后台线程中执行长时间运行的进程,例如可以由SwingWorker提供.有关这方面的更多信息,请阅读Swing中的Concurrency,或者在此站点上搜索类似的问题,因为它再次讨论了很多.
关于你的代码的另一点,永远不要这样做:
catch(IOException e)
{
}
Run Code Online (Sandbox Code Playgroud)
如果你忽略了异常,你实际上是盲目的.至少,打印堆栈跟踪,即:
catch(IOException e)
{
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
同样在这里:
try {
InetAddress IP = InetAddress.getByName(str);
PortScanner P = new PortScanner(IP);
} catch (Exception e) {
e.printStackTrace(); // **** add this!
}
Run Code Online (Sandbox Code Playgroud)
我自己,我在PortScanner构造函数中设置了PortScanner对象,但是会在一个单独的公共方法中运行扫描,比如调用scan().这将允许我在事件线程上设置PortScanner对象,然后通过调用其scan()方法在后台线程中扫描它.有时这更方便.
编辑
我还给PortScanner类添加了一个PropertyChangeListener,以便它可以允许其他类监听它的更改,包括有关端口的信息.这样,您可以在GUI中发布PortScanner端口信息.最简单的方法是让你的PortScanner对象扩展SwingWorker,因为SwingWorkers内置了PropertyChangeSupport.然后你可以使用发布/进程方法对将端口信息发布到GUI而不是在println语句中打印出来.我上面链接的教程描述了如何执行此操作,如果您遇到困难,我们可以帮助您了解详细信息.
| 归档时间: |
|
| 查看次数: |
467 次 |
| 最近记录: |