1

I am stucked at a problem when trying to implement a server/client application for Android.

I implemented a server class which I initialize through the constructor first and then I start an async task for running it.

Here is the server class:

public class Server {
    RestaurantTables activity;
    ServerSocket serverSocket;
    String message = "";

    Handler updateConversationHandler;

    //static final int socketServerPORT = 8080;
    static final int socketServerPORT = 0; // 0 = take any free port

    public Server(RestaurantTables activity) {
        this.activity = activity;
        //Thread socketServerThread = new Thread(new SocketServerThread(this.activity.getHandler()));
        updateConversationHandler = new Handler();
        map = new HashMap();
        try {
            // create ServerSocket using specified port
            serverSocket = new ServerSocket(socketServerPORT);
        }catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        SocketConnectAsyncTask atSockConn = new SocketConnectAsyncTask();
        atSockConn.execute();

    }

    public int getPort() {
        return serverSocket.getLocalPort();
    }

    public void closeSocket() {
        if (serverSocket != null) {
            try {
                serverSocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    private class SocketConnectAsyncTask extends AsyncTask<Void, Void, Void>
    {

        int count = 0;
        Handler mHandler;
        Socket socket;

        @Override
        //public void run() {
        protected Void doInBackground(Void... params) {
            try {
                /*// create ServerSocket using specified port
                serverSocket = new ServerSocket(socketServerPORT);
*/
                while (true) {
                    // block the call until connection is created and return
                    // Socket object
                    socket = serverSocket.accept();
                    count++;
                    message += "#" + count + " from "
                            + socket.getInetAddress() + ":"
                            + socket.getPort() + "\n";
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {

            ReceiveMessage atRecMsg = new ReceiveMessage(socket, this.mHandler);
            atRecMsg.execute();
        }
    }

    class ReceiveMessage extends AsyncTask<Void, Void, Void> {

        private Socket clientSocket;
        private Handler mHandler;
        private BufferedReader input;


        public ReceiveMessage(Socket clientSocket, Handler mHandler)
        {
            this.clientSocket = clientSocket;
            this.mHandler = mHandler;
            try {
                this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected Void doInBackground(Void... params) {
            while(true) {
                try {
                    String read = input.readLine();// blocking
                    Message msg = Message.obtain();
                    msg.obj = read; // Put the string into Message, into "obj" field.
                    msg.setTarget(mHandler); // Set the Handle
                    System.out.println("Here is what I read: " + read);
                    //updateConversationHandler.post(new updateUIThread(read));
                    //mHandler.sendMessage();
                    msg.sendToTarget(); //Send the message

                    try {
                        OutputStream outputStream = clientSocket.getOutputStream();
                        PrintStream printStream = new PrintStream(outputStream);
                        printStream.print("OK");
                        printStream.close();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    Thread.sleep(500);
                } catch (InterruptedException ie) {
                }
            }
            //return null;
        }

    }

    public String getIpAddress() {
        String ip = "";
        try {
            Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface
                    .getNetworkInterfaces();
            while (enumNetworkInterfaces.hasMoreElements()) {
                NetworkInterface networkInterface = enumNetworkInterfaces
                        .nextElement();
                Enumeration<InetAddress> enumInetAddress = networkInterface
                        .getInetAddresses();
                while (enumInetAddress.hasMoreElements()) {
                    InetAddress inetAddress = enumInetAddress
                            .nextElement();

                    if (inetAddress.isSiteLocalAddress()) {
                        ip = inetAddress.getHostAddress();
                    }
                }
            }

        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            ip += "Something Wrong! " + e.toString() + "\n";
        }
        return ip;
    }


}

The call of the server class looks like:

myServer = new Server (this); // this = activity

So I think the server is running then. After trying to connect from the client with following call...

Client myClient = new Client(sServerIpAddress, sServerPort, Commands.this);

... I get the following exception:

W/System.err: java.net.ConnectException: failed to connect to /192.168.200.2 (port 47803) from /:: (port 48982): connect failed: ECONNREFUSED (Connection refused)
W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:138)
W/System.err:     at java.net.PlainSocketImpl.socketConnect(PlainSocketImpl.java:129)
W/System.err:     at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:356)
W/System.err:     at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
W/System.err:     at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
W/System.err:     at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:356)
W/System.err:     at java.net.Socket.connect(Socket.java:616)
W/System.err:     at java.net.Socket.connect(Socket.java:565)
W/System.err:     at java.net.Socket.<init>(Socket.java:445)
W/System.err:     at java.net.Socket.<init>(Socket.java:248)
W/System.err:     at emu.apps.com.jollybell.Client.doInBackground(Client.java:45)
W/System.err:     at emu.apps.com.jollybell.Client.doInBackground(Client.java:20)
W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:333)
W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
W/System.err:     at java.lang.Thread.run(Thread.java:764)
W/System.err: Caused by: android.system.ErrnoException: connect failed: ECONNREFUSED (Connection refused)
W/System.err:     at libcore.io.Linux.connect(Native Method)
W/System.err:     at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:126)
W/System.err:     at libcore.io.IoBridge.connectErrno(IoBridge.java:152)
W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:130)
W/System.err:   ... 17 more

Honestly I have no clue what is going wrong, even after searching for hours in all possible forums.

If it helps, here is the client class:

class Client extends AsyncTask<String, Void, String> {

    public interface ServerResponse {
        void serverResultReceived(String output);
    }

    String sIpAddress, sPort, response;
    private Socket socket;
    private PrintWriter out;

    public ServerResponse delegate = null;

    public Client(String sIpAddress, String sPort, ServerResponse delegate)
    {
        this.sIpAddress = sIpAddress;
        this.sPort = sPort;
        this.delegate = delegate;
    }

    //@Override
    //public void run() {
    @Override
    protected String doInBackground(String... params) {
        try {
            InetAddress serverAddr = InetAddress.getByName(this.sIpAddress);
            socket = new Socket(serverAddr, Integer.parseInt(this.sPort));

            // First send command
            out = new PrintWriter(new BufferedWriter(
            new OutputStreamWriter(socket.getOutputStream())),
            true);
            out.print(params[0]);

            // ... then wait for answer
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
                    1024);
            byte[] buffer = new byte[1024];

            int bytesRead;
            InputStream inputStream = socket.getInputStream();

            /*
             * notice: inputStream.read() will block if no data return
             */
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
                response += byteArrayOutputStream.toString("UTF-8");
            }

        } catch (UnknownHostException e1) {
            e1.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        finally {
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        return response;
    }

    @Override
    protected void onPostExecute(String result) {
        delegate.serverResultReceived(result);
    }
}
5
  • Are u able to access the server without your app? ie PING your server with domain name or ip address. Are u running your app in device or in emulator? Commented Dec 30, 2017 at 11:03
  • Questions seeking debugging help ("why isn't this code working?") must include the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement are not useful to other readers. Please read how to create a minimal reproducible example. Commented Dec 30, 2017 at 11:03
  • Thanks for your replies. I am running my app in the emulator. Unfortunately I could not ping it either. Regarding the tons of code, sorry if I posted that much, I thought somebody might want to copy paste the code for trying it, so this would make it easier for him. Commented Dec 31, 2017 at 6:05
  • Where did you get port number 47803 from? The server listens on port zero, which means a system-allocated port. How did the client get hold of it? And why doesn't your read loop exit when readLine() returns null? Commented Apr 1, 2018 at 6:41
  • I am saving the port in my db to make it possible for the client to connect to it - so this is why I know the port. The client reads the serverconnections then from db. ReadLine() does not return anything because I am not writing the message with a final "/n". Either I have to add it to my sending string or I have to use out.println as I explained below. Commented Apr 3, 2018 at 9:46

1 Answer 1

2

So folks. Been some time ago, but I found out how to resolve my problem.

First of all, in the client there is a small problem. I am writing with "out.print" function and then waiting in the server with function "readLine()".

readLine expects the end of a line so either the string should be send with a final "/n" or function "println" has to be used instead of print.

Second, When I started 2 android devices, they could not communicate to each other. I still did not find out why, but using the same device to run the server and the client application worked for me.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.