readObject() 挂起程序



我刚刚开始学习序列化并尝试实现它。我有一个server,一个client和一个student班。该server将创建我的学生类的初始实例。然后客户端连接到服务器并篡改与学生相关的属性,即提高GPA。

由于某种原因,当我尝试在client类中readObject()时,我的代码没有得到重点。想不通为什么。同样,我对这个话题很陌生,所以如果我误解了它的主要或次要内容,请指出来。任何帮助,不胜感激。

以下是我的课程:

服务器类:

import java.io.*;
import java.net.*;
public class Server
{
   Student s1 = null;
   ServerSocket sock;
   ListeningThread thread;
   public Server(int port) throws IOException {
       sock = new ServerSocket(port);
   } // end of constructor
   // starts the listening thread
   public void start() {
       thread = new ListeningThread();
       thread.start();
   } // end of start method
   //  stops the listening thread
   public void shutdown() throws IOException {
       thread.shutdown();
   } // end of start method
   private class ListeningThread extends Thread
   {
     Student s1 = new Student(0.5, "ABCDEFG", "Computer Science and Pure Math");
     boolean keep_going;
     public ListeningThread() {
         super("The thread that listens");
     }
     public void shutdown() throws IOException
     {
         keep_going = false;
         System.out.println("closing server socket");
         sock.close();
         System.out.println("Waiting for listening thread to exit");
         try { join(); }
         catch(InterruptedException e) {}
         System.out.println("Server shut down");
     }
     public void run()
     {
       // Show student info before connecting to client
        System.out.println("Student Name is : " + s1.getStudentName());
        System.out.println("Student Major is : " + s1.getStudentMajor());
        System.out.println("Student GPA is : "+ s1.getStudentGPA());
         try
         {
           boolean keep_going = true;
           while(keep_going)
           {
             System.out.println("Listening for connection on port "+
                                sock.getLocalPort());
             Socket s = sock.accept();
             ClientHandler handler = new ClientHandler(s);
             handler.start();
             System.out.println("Got a connection");
           }
         } catch(Exception e) {
             e.printStackTrace();
         }
     } // end of run method
   } // end of ListeningThread class
 private class ClientHandler extends Thread
 {
      ObjectOutputStream serverOutputStream = null;
      ObjectInputStream serverInputStream = null;
      Socket socket;
     /*************************************************************************
     * @param socket The Socket object returned by calling accept() on the
     * ServerSocket.
     *************************************************************************/
     public ClientHandler(Socket socket) throws Exception {
         this.socket = socket;
     } // end of constructor
     public void run()
     {
       try
       {
         serverInputStream = new ObjectInputStream(socket.getInputStream());
         serverOutputStream = new ObjectOutputStream(socket.getOutputStream());
         s1 = (Student)serverInputStream.readObject();
         System.out.println("DATA HAS BEEN TAMPERED");
         serverOutputStream.writeObject(s1);
         serverOutputStream.flush();
          // Show student info after connecting to client, once we tampered with it
         System.out.println("Student Name is : " + s1.getStudentName());
         System.out.println("Student Major is : " + s1.getStudentMajor());
         System.out.println("Student GPA is : "+ s1.getStudentGPA());
         serverInputStream.close();
       }catch(Exception e){e.printStackTrace();}
     } // end of run method
   } // end of ClientHandler inner class
}

客户端类:

import java.io.*;
import java.net.*;
public class Main
{
   public static void main(String[] arg) throws Exception
   {
      Student s1 = null;
      Socket socketConnection = new Socket("127.0.0.1", 9876);
      ObjectInputStream clientInputStream = new
         ObjectInputStream(socketConnection.getInputStream());
      ObjectOutputStream clientOutputStream = new
         ObjectOutputStream(socketConnection.getOutputStream());
         //System.out.println("I'VE TAMPERED WITH DATA");
         //clientOutputStream.writeObject(s1);
         /*****************************************************************
          * Funny thing here that stomped me for quite a while is that
          * .readObject() and .writeObject() exceptions aren't handled by
          * IOException, which makes sense. And I was trying to catch an
          * IOException for about 2 hours till I realized that.
          *****************************************************************/
          s1 = (Student)clientInputStream.readObject();
          s1.setStudentGPA(4.00); // <<<---- hehe
          clientOutputStream.writeObject(s1);
          clientOutputStream.flush();
          System.out.println("I'VE TAMPERED WITH DATA 1");
         clientInputStream.close();
         clientOutputStream.close();
         System.out.println("I'VE TAMPERED WITH DATA 1");
   }
}

和我的学生对象类:

import java.io.*;
import java.util.*;
public class Student implements Serializable
{
   private String studentName, studentMajor;
   private double studentGPA;
   Student(double gpa, String name, String major)
   {
      studentName = name;
      studentMajor= major;
      studentGPA = gpa;
   }
   //-------------------------------------------------------
   public String getStudentName()
   {
      return studentName ;
   }
   public String getStudentMajor()
   {
     return studentMajor ;
   }
   public double getStudentGPA()
   {
     return studentGPA ;
   }
   //-------------------------------------------------------
   public void setStudentGPA(double gpa)
   {
     studentGPA = gpa;
   }
}

编辑:

我查看了您的代码,发现您首先读取了该对象,并尝试在客户端和服务器中编写它。

客户端和服务器一开始都不应该读取,因为它们都将等待数据。

更改读取和写入

的顺序,或在单独的线程中实现读取和写入。

旧答案:

方法readObject()应该阻止当前线程,即,在收到一些数据之前,它不会继续。

解决方案是在客户端中的单独后台线程中实现与网络相关的代码。

最新更新