views:

502

answers:

3

Hey everyone,

So I have been working on a 2 player Tic-Tac-Toe game in java that utilizes sockets. All of the socket stuff is working, and I am sending data back and forth successfully between 2 clients and a server.

I have the following classes: Requester, Provider, and TBoard (which extends Serializable).

In the Requester (client) class, I instantiate an object of TBoard (TBoard board = new TBoard()).

I then send that object through the socket to my two clients, via an output stream.

The error I am getting is on the client-side, and it is: Exception in thread "main" java.lang.ClassCastException: java.lang.String

That's happening with:

 board = (TBoard) in.readObject(); in:

 do {
    try {
       board = (TBoard) in.readObject();
       System.out.println(board.print_board());
    } catch (ClassNotFoundException classNot) {
       System.err.println("data received in unknown format");
    }

My print_board() method in the TBoard class is meant to return a 2d array, but for right now (simplification purposes), I have the method returning the string "Hello"...

Does anyone know why this may be happening? I didn't want to bombard you all with code, but please let me know if posting any more may be helpful...

Thanks!


UPDATE:

Here is what I have going on (in more detail) with my Provider (server) class:

 // 1. creating a server socket
 providerSocket = new ServerSocket(20092);

 // 2. Wait for connection
 System.out.println("Waiting for connection...");

 connection1 = providerSocket.accept();
 System.out.println("Connection received from Player 1 "    + 

 connection1.getInetAddress().getHostName());
 connection2 = providerSocket.accept();
 System.out.println("Connection received from Player 2 " + connection2.getInetAddress().getHostName());

 // 3. get Input and Output streams
 out = new ObjectOutputStream(connection1.getOutputStream());

 out2 = new ObjectOutputStream(connection2.getOutputStream());

 in = new ObjectInputStream(connection1.getInputStream());
 out.writeObject("Player 1 has been connected successfully.");
 in2 = new ObjectInputStream(connection2.getInputStream());
 out2.writeObject("Player 2 has been connected successfully.");

 out.flush();
 out2.flush();

 out.writeObject(board);
 out2.writeObject(board);

So I am indeed sending a String in the streams before sending the last object (board). However, I am flushing out the streams beforehand. I also tried reset()'s after the flushes, and it still gave me the IllegalCastException...

+2  A: 

IIRC, the class mentioned in the Exception is the one that was actually found, so in the code you're showing, the error would have to be here:

board = (TBoard) in.readObject();

And a String object instead of a TBoard being read from the stream.

Edit: So you are sending strings in addition to the data. There's your problem. You either have to stop sending those strings, or read them on the receiving side before reading the data. Calling flush() is irrelevant to that - it just ensures that the Strings that you have already written to the stream are in fact sent over the connection and not kept in a buffer.

Michael Borgwardt
Which corresponds nicely with the final details of OPs post
spender
In the server, I send out the TBoard object with:TBoard board = new TBoard();out = new ObjectOutputStream(connection1.getOutputStream());...out.writeObject(board);So I don't see why it's being read as a String...
behrk2
Apparently you are writing a String to the stream as well, somewhere before that part.
Michael Borgwardt
Yes, I am. But I flushed the connection before sending the objects. Please see my update above...Thanks for your help!
behrk2
I think you're confused. You are sending a string. Flushing the connection forces a send. A string will be sent. The first thing that arrives at the other end will be a string, but your code expects a TBoard, and tries to cast the string you just sent to TBoard, causing the error.
spender
+2  A: 

To investigate, I think the easiest would be to visualize (log or debug) the actual class that result from in.readObject(). Sample code:

    Object o = in.readObject();
    System.out.println("Object of class " + o.getClass().getName() + " is " + o);
KLE
KLE-Nice suggestion. I tried that, and got:"Object of class java.lang.String is Player 1" on the first client, and "Object of class java.lang.String is Player 2" on the second client...So should that not be java.lang.String?
behrk2
+1  A: 

There are a couple of possibilities. Assuming you are using ObjectOutputStream (which I think you are), it's possible that the error is arising because you are not fully serializing each object. ObjectOutputStream will try and hold of resending if you don't reset the stream each time.

I would try the following:

1) make sure you flush() and close() the sockets at the appropriate times

2) try calling reset() after each object is sent.

3) check that you are sending and receiving the same object type, just in case.

best of luck.

UberAlex
UberAlex-Please see my update above. How do the flushes look?
behrk2
I think the flush is backwards. It's supposed to come after the write.
UberAlex