4

what I'm trying to do is to send some JSON from an Android phone to a Java server, which works fine. The Android/ client side looks like this:

                    Socket s = new Socket("192.168.0.36", 12390);
                s.setSoTimeout(1500);

                JSONObject json = new JSONObject();
                json.put("emergency", false);
                json.put("imei", imei);
                json.put("lat", l.getLatitude());
                json.put("lon", l.getLongitude());
                json.put("acc", l.getAccuracy());
                json.put("time", l.getTime());


                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
                        s.getOutputStream()));
                out.write(json.toString());
                out.flush();
                s.close();

The server side is this:

        try {
        s = new ServerSocket(port);
    } 
    catch (IOException e) {
        System.out.println("Could not listen on port: " + port);
        System.exit(-1);
    }


    Socket c = null;
    while (true) {
        try {
            c = s.accept();
        } catch (IOException e) {
            System.out.println("Accept failed: " + port);
            System.exit(-1);
        }
        try {

            BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
                String inputLine = null;
            String result = "";
            while ((inputLine = in.readLine()) != null) {
                result = result.concat(inputLine);  
            }
            System.out.println(result);

As I said, all of that works. Now I want to send a message back from the server to the client after it received the message from the client. I extended the code like this, Android/ client side:

                    Socket s = new Socket("192.168.0.36", 12390);
                s.setSoTimeout(1500);

                JSONObject json = new JSONObject();
                json.put("emergency", false);
                json.put("imei", imei);
                json.put("lat", l.getLatitude());
                json.put("lon", l.getLongitude());
                json.put("acc", l.getAccuracy());
                json.put("time", l.getTime());


                BufferedWriter out = new BufferedWriter(new OutputStreamWriter(
                        s.getOutputStream()));
                out.write(json.toString());
                out.flush();

                String inputLine = null;
                String result = "";
                BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));  
                while ((inputLine = in.readLine()) != null) {
                    Log.d(TAG, in.readLine());
                    result = result.concat(inputLine);
                }

And the server side:

        try {
    s = new ServerSocket(port);
} 
catch (IOException e) {
    System.out.println("Could not listen on port: " + port);
    System.exit(-1);
}


Socket c = null;
while (true) {
    try {
        c = s.accept();
    } catch (IOException e) {
        System.out.println("Accept failed: " + port);
        System.exit(-1);
    }
    try {

        BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
            String inputLine = null;
        String result = "";
        while ((inputLine = in.readLine()) != null) {
            result = result.concat(inputLine);  
        }
        System.out.println(result);

    PrintWriter out = new PrintWriter(c.getOutputStream());
    out.write("Hello phone");
    out.flush();
    out.close();

On the client side, nothing ever comes in, it hangs on

                while ((inputLine = in.readLine()) != null) {
                Log.d(TAG, in.readLine());
                result = result.concat(inputLine);
            }

until the socket times out (never enters the loop). I thought it might be a timing problem, for example the server sending out its reply too early and therefore the client never receiving anything, but i tried to put the out.write("Hello phone"); pretty much anywhere in the code, always the same result. Can it have to do with the socket being obtained from ServerSocket and not being able to send out data? What am I missing here, this is bugging me all day ...

Edit: After Nikolais answer, I tried this (client):

                    out.write(json.toString());
                out.newLine();
                out.write("###");
                out.flush();


                String inputLine = null;
                String result = "";
                BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));  
                while ((inputLine = in.readLine()) != null) {
                    if (inputLine.contains("###")) {
                        break;
                    }
                    Log.d(TAG, in.readLine());
                    result = result.concat(inputLine);

                }


                s.close();

and server:

                while ((inputLine = in.readLine()) != null) {

                result = result.concat(inputLine);  
                if (inputLine.contains("###")) {
                    System.out.println("received ###");
                    out.println("Hello phone");
                    out.println("###");
                    out.flush();
                    break;
                }

            }

The idea was to send out the message from the server before the client closes the socket. Still doesnt work ... any hints?

1 Answer 1

3

On the server side you never get to sending your "Hello phone". Not until client closes the socket, but at that point it's useless. This is because in.readLine() blocks until either data is available or EOF, i.e. socket closed.

You need a way to get out of the reading loop - invent (or adopt) some application-level protocol that would tell you that a whole message is received. Common options are fixed length messages, length prefix, delimited, etc.

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

7 Comments

That absolutely makes sense, thank you. Perhaps you could have a look at my edited question, I think this is roughly what you meant?
@user804967 - send a newline after your special code, otherwise readLine() on the other end won't return.
Yes, I was missing that. Put a newline() after "Hello phone" as well as after "###", still the same issue :( The server recognizes the ### String btw, but the client still doesnt even get in the reading loop.
On the client side you consume one extra line with Log.d(TAG, in.readLine()); - that eats your ### marker.
Good idea, I removed that line, but I never enter that loop. If that line had consumed anything, it would have showed up in the logcat. Sorry to bother you guys, but you have ideas and I'm totally out of ideas.
|

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.