0

サーバーとして機能するアンドロイドのアプリを開発しています。つまり、「サーバー」になるタブレットがあり、「サーバー」に接続する他のタブレットがあります。スレッドを節約するために、セレクターで Java NIO を使用しようとしています。しかし、私の問題は、AndroidのスレッドでJavaコードを実行していることですが、スレッドが実行されても何も起こりません。クライアント側では、接続拒否の例外が発生します。コードは Java アプリケーションで実行されていますが、Android では実行されていません。

インターネットの許可も取っています。

Java セレクター:

Thread t = new Thread(new Runnable() {

    private Selector            selector;
    private ServerSocketChannel sChan;
    private List<SocketChannel> sockets;

    public void run() {

        try {
            selector = SelectorProvider.provider().openSelector();
            sChan = ServerSocketChannel.open();
            InetSocketAddress iaddr = new InetSocketAddress(InetAddress.getLocalHost(), 8000);

            sChan.configureBlocking(false);
            sChan.socket().bind(iaddr);

            System.out.println("Running on port:" + sChan.socket().getLocalPort());

            sChan.register(selector, SelectionKey.OP_ACCEPT);
            sockets = new LinkedList<SocketChannel>();

        }
        catch (IOException e) {
            e.printStackTrace();
        }

        Iterator<SelectionKey> it;

        try {
            while (true) {
                selector.select();

                it = selector.selectedKeys().iterator();
                while (it.hasNext()) {
                    SelectionKey key = it.next();

                    it.remove();
                    if (!key.isValid()) {
                        continue;
                    }

                    // Finish connection in case of an error
                    if (key.isConnectable()) {
                        SocketChannel ssc = (SocketChannel) key.channel();
                        if (ssc.isConnectionPending()) {
                            ssc.finishConnect();
                        }
                    }

                    if (key.isAcceptable()) {
                        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                        SocketChannel newClient = ssc.accept();

                        newClient.configureBlocking(false);
                        newClient.register(selector, SelectionKey.OP_READ);
                        sockets.add(newClient);

                        System.out.println("new client: " + newClient.socket().getInetAddress().getHostAddress());
                    }

                    if (key.isReadable()) {
                        SocketChannel sc = (SocketChannel) key.channel();
                        ByteBuffer data = ByteBuffer.allocate(sc.socket().getSendBufferSize());

                        System.out.println("new message: " + sc.socket().getInetAddress().getHostAddress());

                        if (sc.read(data) == -1) {
                            continue;
                        }

                        data.flip();

                        Teste m = (Teste) UdpUtil.byteToMessage(data.array());

                        System.out.println("message: " + m);
                        System.out.println("\n\n" + m.cenas);
                        sc.close();
                    }
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
});
t.start();

クライアント アプリケーション:

InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName("192.168.2.102"), 8000);

    SocketChannel sc = null;

    try {

        // Connect
        sc = SocketChannel.open();
        sc.connect(isa);

        // Read the time from the remote host. For simplicity we assume
        // that the time comes back to us in a single packet, so that we
        // only need to read once.

        byte[] message = UdpUtil.messageToByteMessage(new messages.Teste("hello there"));

        ByteBuffer buf = ByteBuffer.wrap(message);
        sc.write(buf);
    }
    finally {
        // Make sure we close the channel (and hence the socket)
        if (sc != null) {
            sc.close();
        }
}

注: Testeクラスは、 Android間のメッセージとして使用される単なるクラスです。

私もこのコードを試してみましたが、すべてうまくいきましたが、セレクターではうまくいきませんでした。問題が何であるかを明確にしたことを願っています。

前もって感謝します :)

4

2 に答える 2

2

ServerSocketChannel のバインドに使用する new InetSocketAddress() の最初の引数を削除します。現在、127.0.0.1 にバインドしているだけで、他のホストからは見えません。引数を省略すると、0.0.0.0 にバインドされます。これは、「すべてのインターフェイスでリッスンする」ことを意味します。

于 2012-07-20T02:56:35.580 に答える
0

AndroidManifest.xml ファイルに次のように入力して、Android でインターネット許可を要求したことを確認してください。

于 2012-07-16T18:29:51.957 に答える