我已经使用java创建了一个portscanner,但当我单击“执行”时,它就冻结了
下面的代码是我用来创建端口扫描程序的代码,但是,当我单击“扫描”时,它会执行,但gui会冻结,直到它完成扫描,是否有任何可能的方法允许它在扫描时执行其他操作我已经使用java创建了一个portscanner,但当我单击“执行”时,它就冻结了,java,for-loop,freeze,port-scanning,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; impo
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");
}
}
}
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.net.InetAddress;
导入java.net.Socket;
导入java.net.UnknownHostException;
公共类PortScannerGUI扩展JFrame实现ActionListener
{
JPanel面板=新JPanel(空);
JTextField=新的JTextField();
JButton Button=新JButton();
JTextArea=新的JTextArea();
JButton limit=新JButton(“limit”);
公共端口扫描程序GUI()
{
超级();
设置大小(350400);
setDefaultCloseOperation(关闭时退出);
可设置大小(假);
setLocationRelativeTo(空);
LoadUI();
}
公共void LoadUI()
{
面积.立根(20,50,310,310);
setboorder(BorderFactory.createLineBorder(Color.BLUE));
区域设置可编辑(假);
外地挫折(20,10,200,35);
按钮.立根(2301010035);
按钮设置文本(“扫描”);
addActionListener(这个);
面板。添加(字段);
面板。添加(面积);
面板。添加(按钮);
添加(面板);
setVisible(真);
}
公共静态void main(字符串[]args)
{
PortScannerGUI Main=新的PortScannerGUI();
}
@凌驾
已执行的公共无效操作(操作事件arg0)
{
线程运行器=新线程();
Runner.start();
int j=0;
String str=Field.getText();
对于(inti=1;i这是在Swing事件线程(EDT或事件调度线程)中执行长时间运行的进程的典型示例因此,冻结此线程会使您的GUI无法正常工作。我们一次又一次地看到这种情况,解决方案是相同的,而且相对简单:在后台线程中执行长时间运行的过程,如SwingWorker提供的线程。有关此方面的更多信息,请阅读或在本网站上搜索类似问题,请访问因为再次,它被讨论了很多
关于代码的另一点,永远不要这样做:
catch(IOException e)
{
}
如果忽略异常,实际上是盲目的。至少,打印堆栈跟踪,即:
catch(IOException e)
{
e.printStackTrace();
}
这里也一样:
try {
InetAddress IP = InetAddress.getByName(str);
PortScanner P = new PortScanner(IP);
} catch (Exception e) {
e.printStackTrace(); // **** add this!
}
我自己在PortScanner构造函数中设置了PortScanner对象,但会在一个单独的公共方法中运行扫描,比如称为scan()
。这将允许我在事件线程上设置PortScanner对象,然后通过调用其scan()在后台线程中扫描它
方法。有时这更方便
编辑
我还为PortScanner类提供了添加PropertyChangeListener的功能,以便它可以允许其他类侦听它的更改,包括端口信息。这样,您可以在GUI中发布PortScanner端口信息。最简单的方法是让您的PortScanner对象扩展SwingWorkerce SwingWorkers内置了PropertyChangeSupport。然后,您可以使用publish/process方法对将端口信息发布到GUI,而不是在println语句中打印出来。我上面链接的教程介绍了如何执行此操作,如果您遇到问题,我们可以帮助您解决细节问题。这是一个经典的示例在Swing事件线程(EDT或事件调度线程)中执行长时间运行的进程的可能性因此,冻结此线程会使您的GUI无法正常工作。我们一次又一次地看到这种情况,解决方案是相同的,而且相对简单:在后台线程中执行长时间运行的过程,如SwingWorker提供的线程。有关此方面的更多信息,请阅读或在本网站上搜索类似问题,请访问因为再次,它被讨论了很多
关于代码的另一点,永远不要这样做:
catch(IOException e)
{
}
如果忽略异常,实际上是盲目的。至少,打印堆栈跟踪,即:
catch(IOException e)
{
e.printStackTrace();
}
这里也一样:
try {
InetAddress IP = InetAddress.getByName(str);
PortScanner P = new PortScanner(IP);
} catch (Exception e) {
e.printStackTrace(); // **** add this!
}
我自己在PortScanner构造函数中设置了PortScanner对象,但会在一个单独的公共方法中运行扫描,比如称为scan()
。这将允许我在事件线程上设置PortScanner对象,然后通过调用其scan()在后台线程中扫描它
方法。有时这更方便
编辑
我还为PortScanner类提供了添加PropertyChangeListener的功能,以便它可以允许其他类侦听它的更改,包括端口信息。这样,您可以在GUI中发布PortScanner端口信息。最简单的方法是让您的PortScanner对象扩展SwingWorkerce SwingWorkers内置了PropertyChangeSupport。然后,您可以使用publish/process方法对将端口信息发布到GUI,而不是在println语句中打印出来。我上面链接的教程介绍了如何执行此操作,如果您遇到问题,我们可以提供详细帮助。@user1576203:请参阅edit.至于“变更”,我们通常不为您编写代码更改,而是帮助您解决特定问题。您应该先阅读并理解本教程,因为它将指导您必须做的事情。然后继续尝试创建您自己的SwingWorker,如果您遇到问题,请发布另一个有关堆栈溢出的问题。@user1576203:请参阅编辑。至于“更改”,我们通常不会为您编写代码更改,而是帮助您解决特定问题。您应该先阅读并理解教程,因为它将指导您必须做的事情。然后继续尝试创建您自己的SwingWorker,如果您遇到卡滞,请发布另一个有关堆栈溢出的问题。