(ObjectInputStream) first time it works, second time I get an error!

hi,

Using the following code I am sending a query to a server socket using a PrintWriter.println function and retrieve a vector object (results).

Client Code

public Vector getDBResultSet(String query)throws ClientException, IOException{

Object obj =new Object();

if (socket !=null)

{

try{

System.out.println("Sending "+query+" to Server");

writer.println(query);

try{

ois =new ObjectInputStream(input);

while ((obj = ois.readObject()) !=null)

obj = ois.readObject();

}catch (EOFException eofx){

System.out.println("EOF @ object input stream!");

}

finally{

ois.close();

}

return (Vector)obj;

}catch(Exception e){

e.printStackTrace();

thrownew ClientException("<html>Error: <br>"+e.toString()+"#"+e.getMessage()+"</html>");

}finally{

//writer.close();

}

}elsethrownew ClientException("no connection!");

}

Server side code

publicvoid communicate()

{

try{

while (true){

String q = reader.readLine();

Vector vec = db.getResults(q);

oos =new ObjectOutputStream(output);

oos.writeObject(vec);

oos.flush();

oos.close();

}

}catch(Exception e){

e.printStackTrace();

}

}

First time everything goes OK.

Second timeon the Client-Side I get strange errors like "ClassCastException Java.lang.Object" and if I comment out the "while" line I get a "socket closed" error...

any ideas what is wrong with it?

[3334 byte] By [xpantaa] at [2007-11-27 1:03:11]
# 1

That's not quite enough information to be sure what the problem is (e.g. what are the "input" and "output" variables etc), but I'll take a guess:

You have a socket connection, and you create new Object{In,Out}putStreams for it and then close them. You can't do that. When you close the OIS, that will close the InputStream with which you created it, and that in turn closes the socket.

Open the streams once when you connect, keep the stream object around, and close it when you want to close the entire connection.

Incidentally, there is a fair chance you want to use writeUnshared() rather than writeObject(). Or maybe not.

sjasjaa at 2007-7-11 23:38:14 > top of Java-index,Core,Core APIs...
# 2

Thank you. input and output variables are Inputstream and outputStream objects.

However if you notice, I open the ObjectInputStream inside getDBResultSet() method. So whenever this method is called a new ObjectIputStream shall be initialized. That is why I close the ObjectInput/outputStreams right after the try/catch portion.

I tried starting the ObjectInputStream inside the connect method (which initialized the connection with the ServerSocket object) but wheneven connect() was called the GUI hanged!

I don't know what am I doing wrong...

public void connect() throws Exception

{

if (socket == null){

try{

System.out.println("opening connection...to "+host+" at port "+port);

socket = new Socket(host, port);

input = socket.getInputStream();

output = socket.getOutputStream();

in = new DataInputStream(input);

out = new DataOutputStream(output);

reader = new BufferedReader(new InputStreamReader(in));

writer = new PrintWriter(out, true);

//ois = new ObjectInputStream(input);

System.out.println("Connection established!");

}catch(IOException e){

try{

if (socket != null)

socket.close();

System.out.println("ERROR WHILE CONNECTING... SOCKET IS NOW CLOSED!");

}catch(IOException x){

x.printStackTrace();

}

}

}

else

{

throw new ClientException("connection active!");

}

}

xpantaa at 2007-7-11 23:38:14 > top of Java-index,Core,Core APIs...
# 3

Old gotcha.

You must create the ObjectOutputStreams before the ObjectInputStreams.

The order matters because the ObjectOutputStream constructor writes a stream header and the ObjectInputStream constructor reads the header. If both ends of the conversation do "new ObjectInputStream()" first they both forever wait for the other end to write the header.

The javadocs for ObjectInputStream and ObjectOutputStream constructors mention this but it's easy to miss.

Don't open several things, such as a Reader and a DataInputStream, on the same stream. They do their own internal buffering, and things will get mixed up.

You may want to put Buffered{In,Out}putStreams between the socket stream and Data{In,Out}putStreams, for performance.

sjasjaa at 2007-7-11 23:38:14 > top of Java-index,Core,Core APIs...
# 4
thank you very much.I only kept ObjectInput/OutputStreams using a Wrapper object to transmit data between the two ends. I took care when to open both Streams and now I only close them when connection seizes.
xpantaa at 2007-7-11 23:38:14 > top of Java-index,Core,Core APIs...
# 5

You can't use a BufferedReader and an ObjectInputStream on the same socket. They are both buffered and they will steal data from each other. Use ObjectInputStream.readLine() which is inherited from DataInputStream.readLine(), or don't read and write lines at all, use Strings and read/writeObject for them too, or read/writeUTF().

And yes I know DataInputStream.readLine() is deprecated. It is also the only choice in the situation above if you must read and write lines.

ejpa at 2007-7-11 23:38:14 > top of Java-index,Core,Core APIs...
# 6

Yes this is what I did. I got rid off all the stream object but the ObjectInput/OutputStreams. However I didn't know that Data and Object Streams conflict with each other...

One last question.

When the client disconnects I get an EOF Exception on the server side. Can I catch this Exception assuming always that the reason is the client disconnect? (in order to close the server socket peacefully)

xpantaa at 2007-7-11 23:38:14 > top of Java-index,Core,Core APIs...
# 7

> However I

> didn't know that Data and Object Streams conflict

> with each other...

That's not what I said. Any BufferedXXX or ObjectInputStreams will conflict with each other. DataInputStream doesn't buffer but you don't need it in this situation because ObjectInputStream extends it.

> When the client disconnects I get an EOF Exception on

> the server side. Can I catch this Exception assuming

> always that the reason is the client disconnect? (in

> order to close the server socket peacefully)

Yes.

ejpa at 2007-7-11 23:38:14 > top of Java-index,Core,Core APIs...