Java TCP server NIO with Selector in Android

I'm developing an app in android that will act as a server, this is, there will be an tablet that will be the "server" and there will be other tablets that will connect to the "server". I'm trying to use the java NIO with a selector, to save on threads. But my problem is, I have the java code running in a thread in android, but when the thread runs it don't happen nothing. On the client side it gives and exception of Connection Refused. The code is running in a java application, but in android not.

I also have the internet permission.

The java selector:

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();

And the Client application:

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();
        }
}

Note: the Teste class its just an class that will be used as the message between the androids.

I had even tried this code and all went well, but with the selector not. I hope that I made my self clear on what the problem is.

Thanks in advance :)

Answers


Remove the first argument to new InetSocketAddress(), the one you use for binding the ServerSocketChannel. At present you are only binding to 127.0.0.1, which cannot be seen from other hosts. By omitting the argument you are binding to 0.0.0.0, which means 'listen at all interfaces'.


Make sure you have requested the internet permission in Android by going into your AndroidManifest.xml file and putting: uses-permission android:name="android.permission.INTERNET" />


Need Your Help

Why did the designers of ColdFusion decide to index arrays from 1 rather than 0?

coldfusion history

I'm just curious about this really, does anyone know why they broke convention on this one?

Google App Engine: HTTP Error 400: Bad Request

python google-maps google-app-engine google-maps-api-3

I'm working on an application which requires calculating the distance between two locations that were given as input by the user. I'm using Google Map's Distance Matrix API for this purpose. Here's...