gpt4 book ai didi

java - readObject() 挂起程序

转载 作者:行者123 更新时间:2023-11-30 02:21:19 27 4
gpt4 key购买 nike

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

出于某种原因,当我尝试在 client 类中读取 readObject() 时,我的代码无法理解。不明白为什么。再说一遍,我对这个主题非常陌生,所以如果我对它有什么主要或次要的误解,请指出。如有任何帮助,我们将不胜感激。

这是我的类(class):

服务器类别:

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()应该阻塞当前线程,即,在接收到一些数据之前它不会继续。

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

关于java - readObject() 挂起程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46743427/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com