简体   繁体   中英

<Java> Client/Server chat application not responding when compiled

I am trying to create a two way chat program between a client and sever using JavaFX. Whenever I run the programs, Assignment5Server.java and Assignment5Client.java the window freezes and says "not responding". At this point I am stuck on what to do, it seems that the programs run into issues when I set up my streams and try to append the text to the textArea. I feel that I might be missing something in order to get the programs connected? I will post the code I have so far. I would appreciate any help or insight in helping me find the solution!

This is the Assignment5Server.java program which runs as the server

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;



public class Assignment5Server extends Application {
TextArea messages = new TextArea();
String inputMessage;
String outputMessage;
ObjectOutputStream output;
ObjectInputStream input;
Socket clientSocket;
    public void printToTextArea(String text) {

    messages.appendText(text);
}
public void serverChat(String text) {

    try {
        output.writeObject("Server: "+ text + "\n");
        output.flush();
    } catch (IOException e) {

        e.printStackTrace();
    }

    messages.appendText("Server: "+text+ "\n");
}

@Override
public void start(Stage primaryStage)  {

    primaryStage.setTitle("ChatServer");


    messages.setEditable(false);
    messages.setPrefHeight(550);

    Label  serverLabel = new Label("Server");
    Label clientLabel = new Label("Connected to: Client");

    TextField textField = new TextField();
    textField.setOnAction(e->{



        outputMessage = textField.getText();
        serverChat(outputMessage);
        textField.setText("");
    });


    VBox root = new VBox( 5 ,clientLabel, messages,serverLabel, textField);
     root.setPrefSize(600, 600);




     Scene scene = new Scene(root);



     primaryStage.setScene(scene);
     primaryStage.show();


     ServerSocket serverSocket = null;

     try {
        serverSocket = new ServerSocket(80);

        printToTextArea("Waiting to connect to client...\n");


        clientSocket = serverSocket.accept();
        printToTextArea("Connected to client!");



        output = new ObjectOutputStream(clientSocket.getOutputStream());
        output.flush();
        input = new ObjectInputStream(clientSocket.getInputStream());



        /*  while(input.readObject()!= null) 
            {
                inputMessage = (String) input.readObject();
                printToTextArea(inputMessage);
            }

        */

        serverSocket.close();

     } 
     catch (IOException e) {
         e.printStackTrace();
     }







}
public static void main( String[] args) {

    launch(args);

}


}

And the Assignment5Client. java file

 import java.io.BufferedReader;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.UnknownHostException;

 import javafx.application.Application;
 import javafx.stage.Stage;
 import javafx.scene.Scene;
 import javafx.scene.control.Button;
 import javafx.scene.control.Label;
 import javafx.scene.control.RadioButton;
 import javafx.scene.control.TextArea;
 import javafx.scene.control.TextField;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.FlowPane;
 import javafx.scene.layout.StackPane;
 import javafx.scene.layout.VBox;
 import javafx.scene.*;
@SuppressWarnings("unused")

public class Assignment5Client extends Application {
TextArea messages = new TextArea();
String outputMessage;
String inputMessage;
ObjectOutputStream output;
ObjectInputStream input;


public void printToTextArea(String text) {

    messages.appendText(text);
}
public void clientChat(String text) {


    try {
        output.writeObject("Client: "+ text + "\n");
        output.flush();
    } catch (IOException e) {

        e.printStackTrace();
    }


    messages.appendText("Client: "+text + "\n");
}

@Override
public void start(Stage primaryStage) {

    primaryStage.setTitle("ChatClient");


    messages.setEditable(false);
    messages.setPrefHeight(550);

    Label  serverLabel = new Label("Connected to: Server");
    Label clientLabel = new Label("Client");

    TextField textField = new TextField();
    textField.setOnAction(e->{


        outputMessage = textField.getText();
        clientChat(outputMessage);
        textField.setText("");
    });


    VBox root = new VBox( 5 ,serverLabel, messages,clientLabel, textField);
     root.setPrefSize(600, 600);




     Scene scene = new Scene(root);



     primaryStage.setScene(scene);
     primaryStage.show();

     try {

            Socket socket = new Socket("127.0.0.1",80);

            output = new ObjectOutputStream(socket.getOutputStream());
            output.flush();

            input = new ObjectInputStream(socket.getInputStream());

            printToTextArea("Streams Connected!\n");

            /*try {
                while(input.readObject()!= null) {
                    inputMessage = (String) input.readObject();
                    printToTextArea(inputMessage);
                    }
            } catch (ClassNotFoundException e1) {

                e1.printStackTrace();
            }
            */

            socket.close();
     }
          catch (UnknownHostException e) {

              System.out.println("Unknown host exception");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            System.out.println("IO exception");
        }





}

public static void main(String[] args) {
    launch(args);
}
}

The problem

Your try catch block is blocking the JavaFX thread. JavaFX uses the main thread to update the GUI and keep it responsive. You are currently blocking this thread by waiting for a response from the server.

 try {

        Socket socket = new Socket("127.0.0.1",80);

        output = new ObjectOutputStream(socket.getOutputStream());
        output.flush();

        input = new ObjectInputStream(socket.getInputStream());

        printToTextArea("Streams Connected!\n");

        /*try {
            while(input.readObject()!= null) {
                inputMessage = (String) input.readObject();
                printToTextArea(inputMessage);
                }
        } catch (ClassNotFoundException e1) {

            e1.printStackTrace();
        }
        */

        socket.close();
 }
      catch (UnknownHostException e) {

          System.out.println("Unknown host exception");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        System.out.println("IO exception");
    }

There are 2 possible ways to fix this.

  • One is to run it in another thread.
  • Second is to run it non-blocking.

I would suggest going for running it in another thread.

I have an example for this where the client code is in a seperate class. Inside the main class I create an ExecutorService which has a threadpool of 4 threads. What happens here? I create a server and 3 Clients to test out server/client communications.

public static void main(String[] args) throws InterruptedException {

    ExecutorService executorService = Executors.newFixedThreadPool(4);

    executorService.execute(Server::new);
    Thread.sleep(1000);
    executorService.execute(() -> new Client("Ruby"));
    Thread.sleep(1000);
    executorService.execute(() -> new Client("Simon"));
    Thread.sleep(1000);
    executorService.execute(() -> new Client("Peter"));

    executorService.awaitTermination(60, TimeUnit.SECONDS);

}

Now you can specify your own client class and implement your code inside of it. It won't matter that you're blocking that thread since the JavaFX thread can still update the GUI and it will stay responsive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM