2009-09-23 102 views
3

因此,我一直在使用套接字来处理java中的2人井字游戏。所有的套接字工作正常,并且我在2个客户端和服务器之间成功地发送数据。通过java套接字发送对象的问题

我有以下类:Requester,Provider和TBoard(它扩展了Serializable)。

在请求者(客户端)类中,我实例化了TBoard的一个对象(TBoard board = new TBoard())。

然后,我通过套接字将该对象通过输出流发送给我的两个客户端。

我得到的错误是在客户端,它是:

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"); 
    } 

我print_board()在TBoard类方法是为了返回:Exception in thread "main" java.lang.ClassCastException: java.lang.String

这与发生二维数组,但现在(简化目的),我有方法返回字符串“你好”...

有没有人知道为什么会发生这种情况?我不想用代码轰炸你们,但请让我知道如果发布任何更多可能会有所帮助...

谢谢!


UPDATE:

以下是我与我的供应商回事(详细)(服务器)类:

// 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); 

所以我确实是在流发送字符串在发送最后一个对象(板)之前。但是,我预先冲出了溪流。我也试过在刷新后重置(),它仍然给我IllegalCastException ...

+0

为ClassCastException添加一个catch。像catch(ClassCastException CCE){CCE.printStackTrace(); }并向我们展示前几行的结果。我想确切地知道什么线路导致问题 – NawaMan 2009-09-23 07:15:53

+0

他在问题中这么说 - 我首先忽略了这一点 – 2009-09-23 07:17:40

回答

3

IIRC,异常中提到的类是实际发现的类,所以在您显示的代码中,错误将在这里:

board = (TBoard) in.readObject(); 

而不是一个字符串对象,而不是从流中读取TBoard。

编辑: 所以你发送的字符串,除了数据。这是你的问题。您必须停止发送这些字符串,或者在读取数据之前在接收端读取它们。调用flush()与此无关 - 它只是确保已写入流的字符串实际上是通过连接发送的,而不是保存在缓冲区中。

+0

这与OP的最终细节 – spender 2009-09-23 07:16:48

+0

很好地对应在服务器中,我发出了TBoard对象: 012oards board = new TBoard(); out = new ObjectOutputStream(connection1.getOutputStream()); 。 。 。 out.writeObject(board); 所以我不明白为什么它被读作字符串... – littleK 2009-09-23 07:17:21

+1

显然你正在写一个字符串到流,以及该部分之前的某个地方。 – 2009-09-23 07:33:51

2

为了进行调查,我认为最简单的方法就是将从in.readObject()得到的实际类进行可视化(记录或调试)。示例代码:

Object o = in.readObject(); 
    System.out.println("Object of class " + o.getClass().getName() + " is " + o); 
+0

KLE- 不错的建议。我试过了,得到: 第一个客户端上的“java.lang.String类的对象是Player 1”,第二个客户端上的“java.lang.String类的对象是Player 2”... 那么应该不是java.lang.String? – littleK 2009-09-23 07:22:59

1

有几种可能性。假设你正在使用ObjectOutputStream(我认为你是),可能会出现错误,因为你没有完全序列化每个对象。如果您不重置每次流,ObjectOutputStream将尝试并重新发送。

我会尝试以下方法:

1)在适当的时候

2)尝试每个对象发送后调用reset(),请确保您的flush()和close()的插槽中。

3)检查您是否发送和接收相同的对象类型,以防万一。

祝你好运。

+0

UberAlex- 请参阅上面的我的更新。潮红如何看待? – littleK 2009-09-23 07:47:53

+0

我认为冲洗是倒退。它应该在写完之后出现。 – UberAlex 2009-09-23 10:58:52