0

是否可以一次扫描多个端口AsyncTask?我对 完全陌生AsyncTask,所以我不知道我在做什么。即使在阅读了互联网上所有关于AsyncTask(例如 Vogella 等)的教程后,我仍然无法理解如何做到这一点。

这是我目前拥有的代码:

public class MainActivity extends Activity {

    EditText et;
    Button b;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        et = (EditText) findViewById(R.id.editText1);
        b = (Button) findViewById(R.id.button1);
    }

    public void start(View view){
        GetPorts task = new GetPorts();
        task.execute(20,53,80,114,140);
    }

    private class GetPorts extends AsyncTask<Integer, Void, Vector<Integer>> {

        Vector<Integer> openPorts = new Vector<Integer>();

        @Override
        protected Vector<Integer> doInBackground(Integer... ports) {


            for(Integer port: ports){

                try {
                    Socket socket = new Socket();
                    socket.connect(new InetSocketAddress("localhost", port), 500);
                    socket.close();
                    openPorts.add(port);
                } catch (Exception ex) {

                }
            }
            return openPorts;
        }
    }
}

端口 20、53、80 等是我要检查的示例端口(最多可能有 65535 个端口)。我认为检查端口并将它们添加到Vector然后返回这Vector是一个好主意,但我不知道该怎么做。我想知道我的Vector“openPorts”是否会在每个要扫描的新端口时重置,这AsyncTask是否能够同时扫描多个端口?

我已经使用 Java SE 创建了有效的解决方案,我将把它粘贴在这里以澄清我所追求的。

Java SE 代码:

public class Scanner {

    private final String ip;
    private final int sPort, ePort, timeout, poolSize;
    private Vector<Integer> openPorts = new Vector<Integer>();
    private final ExecutorService es;
    private Collection<Future<?>> futures = new LinkedList<Future<?>>();


    public Scanner(String ip, int sPort, int ePort, int timeout, int poolSize) {
        this.ip = ip;
        this.sPort = sPort;
        this.ePort = ePort;
        this.timeout = timeout;
        this.poolSize = poolSize;
        es = Executors.newFixedThreadPool(this.poolSize);

    }

    public Vector<Integer> getPorts() {
        Collections.sort(openPorts);
        return openPorts;
    }

    public void runScanner() {

        for (int startPort = sPort; startPort <= ePort; startPort++) {
            futures.add(es.submit(new Check(ip, startPort, timeout)));
        }

        es.shutdown();

    }

    public void stopScanner(){
        for (Future<?> future : futures) {
            future.cancel(true);
        }
    }

    private class Check implements Runnable {

        private String ip;
        private int port, timeout;

        private Check(String ip, int port, int timeout) {
            this.ip = ip;
            this.port = port;
            this.timeout = timeout;
        }

        public void run() {
            try {
                Socket socket = new Socket();
                socket.connect(new InetSocketAddress(ip, port), timeout);
                socket.close();
                openPorts.add(port);
            } catch (Exception ex) {

            }
        }
    }                                      
}
4

1 回答 1

0

只有当您实例化一个新GetPorts类时(像往常一样),您的向量才会被重置。你的代码看起来很好。如果您的问题是检索 的结果AsyncTask,您有两种主要方法来实现它。

你可以打电话Vector<Integer> v = new GetPorts().execute(20,53,80,114,140).get();,但这通常不是正确的方式。

或者您可以在执行AsyncTask后回调中实现回调。

@Override
protected void onPostExecute(Vector<Integer> result) {
}

AsyncTask应该是这样的:

 private class GetPorts extends AsyncTask<Integer, Void, Vector<Integer>> {

    public interface MyCallbackInterface {
    public void myCallback(Vector<Integer> ports);
    }

    MyCallbackInterface listener;
    Vector<Integer> openPorts = new Vector<Integer>();

    public GetPorts(MyCallbackInterface listener) {
        this.listener = listener;
    }

    @Override
    protected Vector<Integer> doInBackground(Integer... ports) {


        for(Integer port: ports){

            try {
                Socket socket = new Socket();
                socket.connect(new InetSocketAddress("localhost", port), 500);
                socket.close();
                openPorts.add(port);
            } catch (Exception ex) {

            }
        }
        return openPorts;
    }

    @Override
    protected void onPostExecute(Vector<Integer> result) {
         listener.myCallback(result);
    }
}

然后在实现的任务调用者中MyCallbackInterface,您可以执行以下操作:

new GetPorts(this).execute(20,53,80,114,140);

做你想做的事:

 @Override
 public void myCallback(Vector<Integer> ports) {
 }
于 2012-08-17T21:15:17.800 回答