将 doInBackGround 结果发布到 Jtable

问题描述 投票:0回答:0

我正在 Eclipse 中开发一个 Java 网络应用程序,已经有很多细节,应用程序的功能是执行网络 ip 扫描和特定 ip 地址的端口扫描。这是github项目的链接 https://github.com/zentech/IpScannerX

问题? ip 扫描功能工作正常,但我无法解决端口扫描部分。

ip 扫描和端口扫描类都扩展了

SwingWorker
类,您必须实现
doInBackGround()
方法,该方法又创建一个可扫描的 ip/端口池,并将该池成块发送到可调用类。

然后当

result.isDone()
true
时,我将数据添加到包含节点类型对象的
Node
列表中,每个节点都有ip,mac,主机名,端口等......然后调用
process()
方法我将数据添加到
JTable
并发布到应用程序。

ip 扫描器首先完成,端口扫描器运行,我正在登录到终端,我可以看到它正在检测打开的端口。这里的问题是为每个主机收集添加到

Node
列表并发布到
JTable
.

的端口

因为此时

JTable
已经包含了数据。如果更新表或添加到节点和表将自动更新,我不知道发布到表的正确方法是什么。

我应该从 portScanMain 类还是从 ipScanMain 类更新表,一旦 ip 扫描完成,端口扫描就会从 ipScanMain 类启动。

我知道这是网络知识,但我希望有人能看到这里的逻辑。

我只打算发布一个课程,因为发布整个项目毫无意义

/**
 * <h1>PortScanMain</h1>
 * this class is responsible for main logic of scanning
 * and detecting open ports in a host on the network
 * @author George
 * @version 1.0
 */
public class PortScanMain extends SwingWorker<Void, Integer>{   

    final int MAX_PORT = 1024;  
    public Scanner in;
    public String ip;
    public Future<Node> result = null;
    public int startPort = 0;
    final int TIME_OUT = 4000;
    private Node node;
    private JTable table;
    private int hostNum = 0;
    private DefaultTableModel model;
    public PortScanCallable pScan;      
    final int NUM_OF_THREAD = MAX_PORT; //divided by 4 b/c 4 processors so 256 threads 
    public ExecutorService servicePool = Executors.newFixedThreadPool(NUM_OF_THREAD);
    public List<Future<Node>> resultList = new ArrayList<>();
    public int endPort = startPort + (MAX_PORT/NUM_OF_THREAD);
    
    
    /**
     * setter method to set ip address
     * @param ip
     */
    public PortScanMain(Node node, JTable table, int num) {
        System.out.println("Scanning " + node.getIp());
        this.node = node;
        this.table = table;
        this.hostNum = num;
    }
    
    @Override
    protected Void doInBackground() throws Exception {
        model = (DefaultTableModel) table.getModel();
        for(int i = 0; i <= NUM_OF_THREAD/2; i++) { 
            PortScanCallable portScan = new PortScanCallable(node.getIp(), startPort, endPort); //scan 2 ports @time
            result = servicePool.submit(portScan); 
            resultList.add(result);
            startPort = endPort+1; 
            endPort = startPort + (MAX_PORT / NUM_OF_THREAD);
        }
                
        try {
            Thread.sleep(TIME_OUT);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }       
        
        //picking up results
        if(result.isDone()) {
            //print result
            System.out.println(ip + " Open ports ");
            for(Future<Node> future : resultList) {
                for(Integer port: future.get().openPorts) {
                    try {
                        if(future.get() != null) {
                            publish(port);
                        }               
                    } catch (InterruptedException | ExecutionException e) {
                        e.printStackTrace();
                    }
                }           
            }
        }
        return null;
    }

    @Override
    protected void process(List<Integer> chunks) {      
        for(Integer port : chunks) {
            System.out.println(hostNum +" "+ ip +" "+ port);
        }
    }

    @Override
    protected void done() {
        table.setValueAt("22, 80, 443", hostNum, 4);
    }
    
    /**
     * this method will initiate the thread pool and send port ranges 
     * to callable class to be scanned. then pause for 4 sec and
     * finally display results from the scanned ip adress
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public void startPortScanning() throws InterruptedException, ExecutionException {
        
        
        servicePool.shutdown();
        try {
            servicePool.awaitTermination(3, TimeUnit.SECONDS);
            servicePool.shutdownNow();
        } catch (InterruptedException e) {
            
        }
    }   

}


public class PortScanCallable implements Callable<Node>{
    
    List<Integer> portsResult;
    int startPort;
    int endPort;
    Node newNode;
    String ipAddress;
    int timeOut = 1000;
    
    /**
     * Constructor for PortScanCallable. 
     * @param ipAddress
     * @param startPort
     * @param endPort
     */
    public PortScanCallable(String ipAddress, int startPort, int endPort) {
        this.ipAddress = ipAddress;
        this.startPort = startPort;
        this.endPort = endPort;
        newNode = new Node(ipAddress);
        portsResult = new ArrayList<Integer>();
        
    }

    /**
     * this method establishes a socket connection
     * to each port and if port is open, 
     * then adds to result
     * @return newNode
     */
    @Override
    public Node call() throws Exception {
        for (int i = startPort; i <= endPort; i++) {
            try {
                //establishing connection to every port
                Socket socket = new Socket();
                SocketAddress address = new InetSocketAddress(ipAddress, i);
                socket.connect(address, timeOut);                
                if (socket.isConnected()) {
                    System.out.println("CONNECTED: " + i);
                    socket.close();
                    newNode.openPorts.add(i);
                }
            } catch (UnknownHostException e) {
                //e.printStackTrace();
            } catch (SocketTimeoutException e) {
                //e.printStackTrace();
            } catch (ConnectException e) {
                //e.printStackTrace();
            } catch (IOException e) {
                //e.printStackTrace();
            }
        }
        
        return newNode;
    }

}
java networking swingworker
© www.soinside.com 2019 - 2024. All rights reserved.