java - <Java> 客户端/服务器聊天应用程序在编译时没有响应

标签 java sockets javafx crash serversocket

我正在尝试使用 JavaFX 创建客户端和服务器之间的双向聊天程序。每当我运行程序Assignment5Server.java和Assignment5Client.java时,窗口都会卡住并显示“没有响应”。此时我陷入了困境,当我设置流并尝试将文本附加到文本区域时,程序似乎遇到了问题。我觉得为了连接程序我可能会遗漏一些东西?我将发布迄今为止的代码。如果能帮助我找到解决方案,我将不胜感激!

这是作为服务器运行的Assignment5Server.java程序

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);

}


}

还有Assignment5Client。 java 文件

 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);
}
}

最佳答案

问题

您的 try catch block 正在阻塞 JavaFX 线程。 JavaFX 使用主线程来更新 GUI 并保持响应。您当前正在通过等待服务器响应来阻止该线程。

 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");
    }

有两种可能的方法可以解决此问题。

  • 一种是在另一个线程中运行它。
  • 其次是非阻塞地运行它。

我建议在另一个线程中运行它。

我有一个示例,其中客户端代码位于单独的类中。 在主类中,我创建了一个 ExecutorService,它有一个包含 4 个线程的线程池。 这里会发生什么?我创建了一个服务器和 3 个客户端来测试服务器/客户端通信。

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);

}

现在您可以指定您自己的客户端类并在其中实现您的代码。您阻塞该线程并不重要,因为 JavaFX 线程仍然可以更新 GUI 并且它将保持响应。

关于java - <Java> 客户端/服务器聊天应用程序在编译时没有响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48718402/

相关文章:

javascript - JS日期对象通过套接字转换为字符串?

java - Android 和 java 套接字。套接字连接尝试多次才成功

JavaFX:线程 “JavaFX Application Thread” java.lang.RuntimeException 中出现异常:java.lang.reflect.InitationTargetException

java - 将参数传递给 JavaFx

java - 时间戳转换问题

javaPreparedStatement语法问题

java - 用于 Java AWS Lambda 的 POJO 输入处理程序的大写字段

java - Unix下执行Maven命令修改文件内容

java - 让 PrintWriter 在 Servlet 执行后工作 - 当serversocket接受连接时由套接字客户端调用

javafx - javafx 2.1 中 javafx 1.3 的 javafx.lang 包的替代品是什么?