使用AsyncTask扫描端口

时间:2012-08-17 20:56:52

标签: android android-asynctask

是否可以使用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等是我要检查的示例porst(可能有多达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) {

            }
        }
    }                                      
}

1 个答案:

答案 0 :(得分: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) {
 }