This is the code that i used on client socket
Socket connected = Server.accept();
ObjectOutputStream oos = new ObjectOutputStream(connected.getOutputStream());
oos.writeObject(dPFPSample.serialize());
This the code that i used on server socket
Socket clientSocket = new Socket("localhost", 5002);
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
DPFPSample dpfpSample = (DPFPSample) ois.readObject();
i got an error java.lang.ClassCastException exception on ois.readObject() line
I would assume that your DPFPSamle.serialize() returns something different then DPFPSamle. I'd say you don't need to call any serialization method. The stream will handle it. So just call writeObject(dPFPSample)
In order for this to work your class (the one you are trying to send - i.e. DPFPSample) must implement the java.io.Serializable interface.
Related
I have the following code that works (please assume that hostname and port are initialized to their proper values, and that Message is a serializable class):
//Example 1 - everything works as expected
Message message = new Message();
try(Socket serverSocket = new Socket(hostname, port))
{
ObjectOutputStream outStream = new ObjectOutputStream(serverSocket.getOutputStream());
outStream.writeObject(message);
outStream.flush();
ObjectInputStream inStream = new ObjectInputStream(serverSocket.getInputStream());
Object response = inStream.readObject();
}
When I move the instantiation of the ObjectInputStream to occur immediately after the ObjectOutputStream instantiation, execution of my application hangs indefinitely:
//Example 2 - client locks up
Message message = new Message();
try(Socket serverSocket = new Socket(hostname, port))
{
ObjectOutputStream outStream = new ObjectOutputStream(serverSocket.getOutputStream());
ObjectInputStream inStream = new ObjectInputStream(serverSocket.getInputStream());
outStream.writeObject(message);
outStream.flush();
Object response = inStream.readObject();
}
I'm looking for a good explanation as to why the second example locks up consistently, and the first example seems to work without a hitch. Strangely, if I use a debugger (Eclipse debugger) on the client and server with this second example, I'm seeing the message make it through to the server, so the writeObject() call is being executed. However, in the client, the debugger gets stuck on the constructor for the ObjectInputStream.
If we go and have a read of the API docs for the ObjectInputStream constructor
The important part:
This constructor will block until the corresponding ObjectOutputStream
has written and flushed the header.
Constructing an ObjectOutputStream writes a header to the stream. Constructing an ObjectInputStream reads it. If both ends construct the ObjectInputStream first, you will therefore get a deadlock.
Solution: construct the ObjectOutputStream first, at both ends, to make sure it can't happen.
I set up a client and server sockets. When I use classes ObjectOutputStream and ObjectInputStream and the method readObject/writeObject everything works fine.
It simulates communication with a robot that I know for sure interprets correctly only method
DataOutputStream.writeBytes.
So I set up the new architecture for simulation since the robot is not available for testing on a daily basis.
In the following code where ObjectOutputStream/ObjectInputStream readObject/writeObject were replaced with DataInputStream/DataOutputStream writeBytes and IOutils.toByteArray.
The server socket correctly receives the message but when it tries to write back a response I get a broken pipe as if the connection was closed somewhere.
Notice that I never close sockets or streams because the robot can answer even after 30 seconds.
Any help to make DataOutputStream.writeBytes work would be appreciated.
Here's the non-working code:
Client:
Socket serverSocket = new Socket("server", 9899);
DataOutputStream outputStream = new DataOutputStream(serverSocket.getOutputStream());
//ObjectOutputStream outputStream = new ObjectOutputStream(serverSocket.getOutputStream());
//outputStream.writeObject("\n" + "message" + "\r");
outputStream.writeBytes("\n" + "message" + "\r");
outputStream.flush();
DataInputStream inputStream = new DataInputStream(serverSocket.getInputStream());
//ObjectInputStream inputStream = new ObjectInputStream(serverSocket.getInputStream());
byte [] bytes = IOUtils.toByteArray(inputStream);
String serverResponse = new String(bytes,"UTF-8");
// String serverResponse = (String)inputStream.readObject();
Server:
ServerSocket serverSocket = new ServerSocket(9899);
while (true) {
Socket socket = serverSocket.accept();
//ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
byte [] bytes = IOUtils.toByteArray(inputStream);
String message = new String(bytes,"UTF-8");
//String message = (String) inputStream.readObject();
Thread.sleep(15000);
//ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
//outputStream.writeObject("server response");
outputStream.writeBytes("server response"); //EXCEPTION THROWN HERE FOR BROKEN PIPE
outputStream.flush();
}
Thanks for your time
IOUtils.toString(InputStream) must read the stream until its end, which would imply that the peer has disconnected. So you can't write to it.
If you're exchanging Strings with data streams you should use writeUTF() and readUTF().
Or read and write lines, with a BufferedReader/Writer.
Based on the following information from my prof:
The client creates ObjectOutputStream and ObjectInputStream objects to send the request, and to receive the reply. The CalculateClient constructor is:
public CalculateClient( String host, int port )
throws IOException
{
/* determine the address of the server and connect to it */
serverHost = InetAddress.getByName( host );
serverPort = port;
calculate = new Socket( serverHost, serverPort );
OutputStream out = calculate.getOutputStream();
request = new ObjectOutputStream(
new BufferedOutputStream( out ));
request.flush();
// ObjectInputStream blocks until
// the connected side flushes its ObjectOutputStream
InputStream in = calculate.getInputStream();
reply = new ObjectInputStream( in );
}
In network applications, the construction order of the input and output socket streams when using object streams is important. The ObjectOutputStream must be created first. It then should be flushed. The ObjectInputStream can then be created.
He doesn't elaborate as to why. Why is this true?
It is explained in the comments of the code you posted, isn't it?
// ObjectInputStream blocks until
// the connected side flushes its ObjectOutputStream
So if you try to create the ObjectInputStream the constructor waits until the corresponding ObjectOutputStream's flush() method is called. Since you haven't created it yet, guess what happens?
As an alternative to asking this question, you could have simply switched the creation order and observed the results. It takes arguably less effort on your part and as a bonus you've learned how to problem-solve and think critically.
I have a client class and a server class. There is a client method which I use to call the server and my code hangs if I try use this method more than once during a jvm session.
Client code's main method:
methodA();
methodA();
ois.close(); //ObjectInputStream
oos.close(); //ObjrctOutputStream
is.close(); //InputStream
os.close(); //OutputStream
socket.close();
Client code's methodA() looks like this:
os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
oos.writeObject(obj);
is = socket.getInputStream();
ois = new ObjectInputStream(is);
Object o = ois.readObject();
Server code's main method looks like:
while (true) {
Socket socket = serverSocket.accept();
is = socket.getInputStream();
ois = new ObjectInputStream(is);
Object o = ois.readObject();
servermethod();
}
oos.close();
ois.close();
is.close();
os.close();
serverSocket.close();
The server's serverMethod() looks like:
os = socket.getOutputStream();
oos = new ObjectOutputStream(os);
Object ob = getObject() ; //this method is working fine
oos.writeObject(ob);
What I wanted to do was to have the client call the server a few times using methodA(). I might not be handling the streams correctly. Any help?
There are definitely a few things wrong with this code:
You are creating ObjectInputStream and ObjectOutputStream repeatedly on top of the same streams. This is not how how they are supposed to be used. What you are supposed to do is create the ObjectXxxStream once, and then call readObject or writeObject multiple times on the same ObjectXxxStream. If you are sending the same object multiple times, you need to call reset before writing the object again.
You are not flushing the streams. If you don't flush after writing, there is no guarantee that the serialized representation will get sent to the other end ... where something is waiting for the bytes to arrive.
Your server end code is written in a way to read only one object and write only one object to a newly created Socket. Hence you try to reuse the Socket a second or nth time, it doesn't get back a response from the server. There are 2 ways to fix it.
You can fix on the server end : This will be an elaborate change, but better use of resources. You don't stop reading the stream until it is closed.
You fix it in the client end : Instead of creating the Socket outside the main method, you create the Socket inside MethodA(). Easy and dirty solution though.
I am having trouble bouncing object between the client and the server.
Create an object. Update some fields. Send to Server. (this part works)
SomeObject thisObject = new SomeObject();
thisObject.setSomeValue(13); // update object to be sent
PrintStream toServer = new PrintStream(sock.getOutputStream());
ObjectOutputStream oos = new ObjectOutputStream(toServer);
oos.writeObject(thisObject);
oos.close();
toServer.println(oos); // send object to server
toServer.flush();
Right after this, server further updates some value and sets it to 1919;
ObjectInputStream objFromClient = new ObjectInputStream(new BufferedInputStream(
sock.getInputStream()));
Served thisObject = (Served) objFromClient.readObject();
thisObject.setSomeValue(1919);
Server then sends the object back to client
toClient = new PrintStream(sock.getOutputStream());
ObjectOutputStream oos = new ObjectOutputStream(toClient);
oos.writeObject(thisObject);
oos.close();
objFromClient.close();
sock.close();
But when the time comes to pick up the object back on the client side .. programs fails with Socket Closed exception
ObjectInputStream objFromServer = new ObjectInputStream(
new BufferedInputStream(sock.getInputStream())); //java.net.SocketException: Socket is closed
thisObject = (Served) objFromServer.readObject();
....
Please help me understand the issue
My guess is you're using the same Socket to both send and receive from the client. When you close the ObjectOutputStream on the client, this closes the underlying OutputStream, which closes sock. Then, when you try to reuse it below, it's been closed and throws an exception.
Instead, wait for the transaction to finish before closing your resources in the client code (which should be done in a finally block by the way). Or, if waiting is problematic, use a new Socket instead.