【问题标题】:Question with sending object over java sockets通过 Java 套接字发送对象的问题
【发布时间】:2009-09-23 07:06:46
【问题描述】:

所以我一直在用 Java 开发一个使用套接字的 2 人井字游戏。所有的套接字都在工作,我在 2 个客户端和一个服务器之间成功地来回发送数据。

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

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

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

我得到的错误是在客户端,它是:Exception in thread "main" java.lang.ClassCastException: java.lang.String

这发生在:

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

我在 TBoard 类中的 print_board() 方法旨在返回一个二维数组,但现在(为了简化),我有返回字符串“Hello”的方法...

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

谢谢!


更新:

这是我对 Provider(服务器)类所做的(更详细的):

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

所以我确实在发送最后一个对象(板)之前在流中发送了一个字符串。但是,我事先冲洗了溪流。刷新后我还尝试了 reset(),但它仍然给了我 IllegalCastException...

【问题讨论】:

  • 为 ClassCastException 添加更多捕获。像 catch(ClassCastException CCE) { CCE.printStackTrace();并向我们​​展示前几行结果。我想确定是哪条线路导致问题
  • 他在问题中这么说 - 我一开始也忽略了这一点

标签: java sockets object


【解决方案1】:

IIRC,异常中提到的类是实际找到的类,因此在您显示的代码中,错误必须在这里:

board = (TBoard) in.readObject();

从流中读取一个 String 对象而不是一个 TBoard。

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

【讨论】:

  • 这与 OP 帖子的最终细节非常吻合
  • 在服务器中,我发送 TBoard 对象: TBoard board = new TBoard(); out = new ObjectOutputStream(connection1.getOutputStream()); . . . out.writeObject(board);所以我不明白为什么它被读取为字符串...
  • 显然您也在向流中写入一个字符串,在该部分之前的某个位置。
  • 是的,我是。但是我在发送对象之前刷新了连接。请在上面查看我的更新...感谢您的帮助!
  • 我想你很困惑。您正在发送一个字符串。刷新连接会强制发送。将发送一个字符串。到达另一端的第一件事将是一个字符串,但您的代码需要一个 TBoard,并尝试将您刚刚发送到 TBoard 的字符串强制转换,从而导致错误。
【解决方案2】:

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

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

【讨论】:

  • KLE- 不错的建议。我试过了,在第一个客户端上得到:“类 java.lang.String 的对象是播放器 1”,在第二个客户端上得到“类 java.lang.String 的对象是播放器 2”......所以不应该是 java.lang.String 吗?
【解决方案3】:

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

我会尝试以下方法:

1) 确保在适当的时间刷新()和关闭()套接字

2) 在发送每个对象后尝试调用 reset()。

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

祝你好运。

【讨论】:

  • UberAlex- 请在上面查看我的更新。冲洗看起来如何?
  • 我认为冲洗是倒退的。它应该在写入之后。
猜你喜欢
  • 2014-01-11
  • 2021-01-11
  • 2012-08-29
  • 2012-03-13
  • 2015-08-31
  • 2014-03-24
  • 2017-03-20
  • 2011-12-23
相关资源
最近更新 更多