Brad
Brad

Reputation: 33

BufferedReader readLine skipping every second line

I'm using sockets to communicate between a server and client. For some reason though, the client skips every second line that the server has sent.

Client's code:

    ...

    out.println(console.readLine());                //Client initiates (sent to server)

    while ((userOut = in.readLine()) != null)       //Waits for response
    {
        System.out.println("Server says: " + userOut);  //Prints response

        userIn = console.readLine();                //Gets user input
        out.println(userIn);                        //Sends user input to server
    }

    ...

Servers Code:

    ...

    while ((clientIn = in.readLine()) != null)  //Waits for clients message
    {
        System.out.println("Client says: " + clientIn); //Print clients message

        //Send appropriate response
        if (clientIn.equals(CLIENT_INSTRUCTION_LOGCALC))
        {
            out.println(SERVER_RESPONSE_LOGCALC_OK); //Send response to client
            System.out.println("Message sent: " + SERVER_RESPONSE_LOGCALC_OK); //Print response sent
        }

        else if (clientIn.equals(CLIENT_INSTRUCTION_SB))
        {
            out.println(SERVER_RESPONSE_SB_CHANGE);
        }

        else if (clientIn.equals(CLIENT_INSTRUCTION_BYE))
        {
            out.println(SERVER_RESPONSE_BYE_OK);
        }

        else if (clientIn.equals(CLIENT_INSTRUCTION_END))
        {
            out.println(SERVER_RESPONSE_END_OK);
        }

        else
        {
            out.println(SERVER_RESPONSE_INPUT_ERR);
        }
        ...

An example of using this displays (client first):

 LOGCALC
 Server says: LOGCALC: OK
 LOGCALC
 Server says: 

Server:

Client says: LOGCALC
Message sent: LOGCALC: OK

Client says: LOGCALC
Message sent: LOGCALC: OK

Hopefully you can see that in the second LOGCALC message sent to the server, the server responded, but the client did not receive the servers response.

Any thoughts?

Upvotes: 3

Views: 2009

Answers (3)

Femi
Femi

Reputation: 64700

Looking at your output, it appears that you have an extra linebreak in SERVER_RESPONSE_LOGCALC_OK, since System.out.println("Message sent: " + SERVER_RESPONSE_LOGCALC_OK); has an extra line after it in the server output. I'd remove the extra newline or use a simple out.print(SERVER_RESPONSE_LOGCALC_OK) instead of out.println(SERVER_RESPONSE_LOGCALC_OK);. This should solve your skipping problem.

The underlying flaw you're experiencing is because you only read one line at a time and then wait for user input before reading another line instead of as many lines as are available before waiting for user input. I'm betting that if you do something like the code below in the client you will see different output.

out.println(console.readLine());                //Client initiates (sent to server)

    while ((userOut = in.readLine()) != null)       //Waits for response
    {
        System.out.println("Server says: " + userOut);  //Prints response

        if(!in.available()){
          userIn = console.readLine();                //Gets user input
          out.println(userIn);                        //Sends user input to server
        }
    }

Upvotes: 0

Sanjay T. Sharma
Sanjay T. Sharma

Reputation: 23208

The client definitely receives "some" sort of message hence the printed "Server says" part. It seems as though an extra new line was somehow written by the server when sending the "first response" to the client which results in an empty string being read on the second iteration. It would be worth inspecting/debugging the value of the userOut in the second case.

Also, I'm not sure whether it's intentional but I see a empty line in case of the server output. Assuming it's the posted code snippet doing all the outputting, where is that extra newline coming from?

Upvotes: 1

Grim
Grim

Reputation: 1976

readLine()

scans for \r\n, by \r only or by \n only.

i think, the server may answer by \n\r-linebreak, in this case youll become your double-linebreak (one for \n, anotherone for \r).

As far as i see, this might not be an problem to the functionality of your code. so, to skip the logging-problem: you can check for empty userOut (check by emptyness).

Upvotes: 0

Related Questions