Waterblade85
Waterblade85

Reputation: 43

Strange behavior in a simple chat using Java

I started to study java last month, and now I'm trying to write a simple chat program but I encountered something strange, and I was curious for the reason behind it.

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class Server {
public static void main(String[] args) throws IOException {
    String text = "";
    ServerSocket ss = new ServerSocket(21025);
    while (true){

        System.out.println("Waiting...");
        Socket s1 = ss.accept();
        System.out.println("Connection accepted from "+s1.getInetAddress());
        PrintStream pout = new PrintStream(s1.getOutputStream());
        pout.println("Connected to the server");

        new Thread(new Ricevitore(s1)).start();
     }
  }
}

public class Ricevitore implements Runnable {
String text = "";
Socket skt;
public Ricevitore(Socket skt){
    this.skt = skt;
}
@Override
public void run() {
    while (!text.equalsIgnoreCase("end")) {
        try {
            InputStream in = skt.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            text = br.readLine();
            if (!text.equalsIgnoreCase("end"))
            System.out.println(text);
        }
        catch (IOException e){}
    }
  }
}

public class Client {
public static void main(String[] args) throws IOException {

    //Create a socket
    try (Socket s = new Socket("127.0.0.1", 21025)) {
        String text="";
        while(!text.equalsIgnoreCase("end")) {

           //Allows messages from server
            InputStream in = s.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            if (br.ready()) {
                Scanner server = new Scanner(br);
                String testoServer = br.readLine();
                System.out.println(testoServer);
            }

            //Allows to send text to the server
            OutputStream out = s.getOutputStream();
            PrintStream pout = new PrintStream(out);

            Scanner tastiera = new Scanner(System.in);
            text = tastiera.nextLine();
            pout.println(text);

        }
    }
  }
}

This is the complete program for the moment, my question is this: Since I wanted to avoid printing the word "end" to close the program, I inserted

 if (!text.equalsIgnoreCase("end"))

but after that the server does not display the message "connected to server" unless I first input something through the client. If I comment out that if statement, both messages "Connection accepted" and "Connected to server" got printed at the same time as intended. I don't know if my question is clear, and I'm rather interested in learning why something like this happens.

If there are other things which any of you think is wrong I'll be happy to here about them.

Upvotes: 4

Views: 119

Answers (1)

Alexey Ivanov
Alexey Ivanov

Reputation: 11868

I have only a wild guess which looks probable though.

In your client you read the message from the server if br.ready() returns true. It may happen that this function returns false, and the client goes to waiting for user's input.

After you send a message from the client to the server, the client repeats the test and now gets the message from the server.

I cannot explain why removing if (!text.equalsIgnoreCase("end")) in server's code makes the issue go away. That line isn't even executed until you send a message from the client.

So I think it's just a coincidence. There are two processes involved, and the outcome depends on how fast code executes in either process.

I ran your example many times, and once I did not receive the greeting from the server even though the if above was in its place.


A general suggestion for your code: you don't need to create input/output streams as well as Scanner on each iteration, you should do it only once.

To end communication session, you can just close PrintStream in your client as soon as you receive end from user. Your server will get null from br.readLine(). At this point, you close br and complete run().

Upvotes: 1

Related Questions