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、それを達成する主な方法は 2 つあります。

電話をかけることもできます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 に答える