Reputation: 141
I just started learning about Serialization and tried to implement it. I have a server
, a client
and a student
class. The server
creates an initial instance of my student class. The client then connects to the server and tampers with the attributes associated with the student , i.e. bumps up the GPA.
For some reason my code does not get the point when I try to readObject()
in the client
class. Can't figure out why. Again, I'm very new to this topic so if I'm misunderstanding something major or minor about it please point it out. Any help is appreciated.
Here are my classes:
SERVER 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
}
CLIENT 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");
}
}
AND MY STUDENT OBJECT CLASS:
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;
}
}
Upvotes: 1
Views: 716
Reputation: 16379
EDIT:
I looked through your code and found that you have read the object first and tried to write it next in both client and the server.
Both client and server should not be reading at first because both of them will be waiting for data.
Either change the order of read and write, or implement read and write in separate threads.
Old answer:
The method readObject()
is supposed to block the current thread, i.e., It will not proceed until some data is received.
The solution would be to implement your network related code in a separate background thread also in the client.
Upvotes: 2