Java客户端在尝试从Java服务器创建ObjectInputStream时冻结

Java客户端在尝试从Java服务器创建ObjectInputStream时冻结,java,networking,serialization,objectinputstream,Java,Networking,Serialization,Objectinputstream,我正在使用Java客户机/服务器,它将通过字符串命令进行通信。服务器已接近完成,但从服务器创建ObjectInputStream时,客户端将冻结。我尝试过用几种不同的方法更改服务器上的I/O流,但无论我做什么,最终程序都冻结在同一行上 服务器代码: public class Server { //a lot of other methods public void launchServer(){ // Text area for displaying server console

我正在使用Java客户机/服务器,它将通过字符串命令进行通信。服务器已接近完成,但从服务器创建ObjectInputStream时,客户端将冻结。我尝试过用几种不同的方法更改服务器上的I/O流,但无论我做什么,最终程序都冻结在同一行上

服务器代码:

public class Server {
  //a lot of other methods

  public void launchServer(){
  // Text area for displaying server console
    TextArea ta = new TextArea();

    // Create a scene and place it in the stage
    Stage console = new Stage();
    Scene scene = new Scene(new ScrollPane(ta), 450, 200);
    console.setTitle("Server"); // Set the stage title
    console.setScene(scene); // Place the scene in the stage
    console.show(); // Display the stage

    new Thread( () -> {
      ServerSocket serverSocket = null; Socket socket = null;
      ObjectInputStream fromClient = null; ObjectOutputStream toClient = null;

      Platform.runLater( () -> {
        ta.appendText("Server started at " + new Date() + '\n');
      });

      // Create a server socket
      try{
        serverSocket = new ServerSocket(8000); 

        while (true) {
          socket = serverSocket.accept();

          Platform.runLater( () -> {
            ta.appendText("Thread started at " + new Date() + '\n');
          });

          new MyThread(socket).start();
        }
      }
      catch(IOException e){e.printStackTrace();}
    }).start();
  }
}
内容如下:

class MyThread extends Thread{
  protected Socket socket;
  private String command;
  ObjectInputStream fromClient = null;
  ObjectOutputStream toClient = null;
  Homework6French schoolServer;
  Connection connection = schoolServer.connection;

  public MyThread(Socket clientSocket) {
    this.socket = clientSocket;
  }

  public void run() {
    try {
      // Create data input and output streams
      fromClient = new ObjectInputStream(socket.getInputStream());
      toClient = new ObjectOutputStream(socket.getOutputStream());

      while (true) {
        //read the command from the client
        command = (String) fromClient.readObject();

        //read the first word of the command, and cut it out of the command
        String comStart = command.substring(0, 3);
        command = command.substring(4);

        //run method based on what first word of command was
        switch(comStart){
          case "GGr":
            getGrade(); break;
          case "GSt":
            getStudents(); break;
          case "GCo":
            getCourses(); break;
          default:
            toClient.writeChars("Command not recognized"); break;
        }
      }
    }
    catch(IOException e){e.printStackTrace();}
    catch(ClassNotFoundException e){e.printStackTrace();}
    finally{
      try{
        fromClient.close();
        toClient.close();
      }
      catch(Exception e){e.printStackTrace();}
    }
  }
}
客户:

public class Client {
  //member data
  ObjectOutputStream toServer = null;
  ObjectInputStream fromServer = null;

  public void start(Stage primaryStage) {

    //...

    try {
      // Create a socket to connect to the server
      Socket socket = new Socket("localhost", 8000);
      System.out.println("socket made");

      // Create an input stream to receive data from the server
      fromServer = new ObjectInputStream(socket.getInputStream());
      System.out.println("fromSerrver made");
      // Create an output stream to send data to the server
      toServer = new ObjectOutputStream(socket.getOutputStream());
      System.out.println("toServer made");
    }
    catch (IOException ex) {
      ex.printStackTrace();
    }
  }
}
服务器本身工作正常,客户端启动正常,打印“socket Make”,然后卡住。另外值得注意的是,在客户机代码中的try语句之前,定义并创建了一个JavaFX阶段,窗口出现,但按钮从未出现在窗口中


我认为也许我需要在MyThread内部和调用MyThread之前定义I/O流,但是如果我试图在接受套接字之前创建InputStream,就会抛出NullPointerException。我如何理解此InputStream冻结客户端的原因?

您必须先创建并刷新
ObjectOutputStream
,在
ObjectInputStream
之前,至少创建并刷新一端。确保这一点的安全方法是两头都做

原因是对象输出流在构造时创建流头,而对象输入流在构造时读取流头。因此,如果两个对象输入流都是先构造的,则会死锁

如果在接受套接字之前尝试创建InputStream,则会引发NullPointerException


当然是。
Socket
变量仍然为空。我不知道你为什么要尝试,或者在这里提及。

我不知道你必须冲水。谢谢你帮我省去了头痛,chief@AndrewtheProgrammer我提到这是为了安全。如果没有基础的
缓冲输出流
,则不需要此选项。