java - 在 Java 中重用 ObjectOutputStreams

标签 java multithreading networking file-io objectoutputstream

我正在重用 ObjectOutputStream 在两个客户端之间发送更新,这是服务器代码,

 public void run() {

    try {
        toPlayer1.writeBoolean(true);
        toPlayer1.flush();

        while (true) {

            try {
                found = (boolean[][]) fromPlayer1.readObject();
                player1Int = fromPlayer1.readInt();

            } catch (Exception ex) {
                // Handle  exception here...
            }

            if (isWon(player1Int)) {
                toPlayer1.writeInt(P1_WON);
                toPlayer1.flush();
                toPlayer2.writeInt(P1_WON);
                toPlayer2.flush();

                sendMove(toPlayer2, found, player1Int);
                break;
            } else {
                toPlayer2.writeInt(CONTINUE);
                toPlayer2.flush();

                sendMove(toPlayer2, found, player1Int);
            }

            try {
                found = (boolean[][]) fromPlayer2.readObject();
                player2Int = fromPlayer2.readInt();

            } catch (Exception ex) {
                // Handle  exception here...
            }

            if (isWon(player2Int)) {
                toPlayer1.writeInt(P2_WIN);
                toPlayer1.flush();
                toPlayer2.writeInt(P2_WIN);
                toPlayer2.flush();
                sendMove(toPlayer1, found, player2Int);
                break;
            } else {
                toPlayer1.writeInt(CONTINUE);
                toPlayer1.flush();

                sendMove(toPlayer1, found, player2Int);
            }
        }
    } catch (IOException ex) {
        System.err.println(ex);
    }
}

private void sendMove(ObjectOutputStream out, boolean[][] found, int score) throws IOException {

    try {
        out.reset();
        out.writeObject(found);
        out.writeInt(score);
        out.flush();
    } catch (Exception ex) {
       // Handle  exception here...
    }
    out.writeInt(score);
}

问题似乎是有些消息没有正确传递,有什么建议吗?我是否正确使用 flush() ?我添加了重置();还是不行

更新,这些是流: 公共(public)无效运行(){

    try {
             toPlayer1 = new ObjectOutputStream(player1.getOutputStream());
             fromPlayer1 = new ObjectInputStream(player1.getInputStream());
             toPlayer2 = new ObjectOutputStream(player2.getOutputStream());
             fromPlayer2 = new ObjectInputStream(player2.getInputStream());

问候,c

最佳答案

如果您希望再次发送一个或多个对象,您需要调用reset()ObjectOutputStream 对象上。

reset() 解决的问题是,当您在对象流中发送对象时,协议(protocol)会尝试保留对象身份。第一次发送时,流发送对象状态。随后,它只是发送一个标记,上面写着(实际上)“使用我之前发送给你的这个对象”。

reset() 方法(实际上)对 ObjectOutputStream 说……“忘记我之前发送的所有对象”。

所以如果你想发送同一个对象两次,你需要做这样的事情:

  out.writeObject(found);
  // change the state of 'found'
  out.reset();
  out.writeObject(found);

请注意,这不会影响使用相应的 write 方法发送的原始值。原始值没有“身份”,每次都按字面意思发送。


我还应该指出以下是非常糟糕的做法

        } catch (Exception ex) {
        }

你默默地忽略了所有异常。这是懒惰和危险的,你很可能会后悔。 (即使在 SO 问题中的示例代码中也不要这样做......因为有人可能会复制你的错误代码或者一些 Java 初学者可能会效仿你的坏习惯。)

关于java - 在 Java 中重用 ObjectOutputStreams,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20821423/

相关文章:

java - 尝试在立方体表面渲染纹理

java - Tomcat 7 CometProcessor 上缺少 cometd 事件

java - 同时调用/运行同步方法

c++ - 使用 C++11 异步时 Libusb 挂起

windows - 最大线程数

c - iptables 的队列处理程序 : Why does it stuck during receive ICMP packets?

java - 不使用网络在本地连接到 Apache Tomcat

java - 使用默认配置配置 gradle 任务问题

android - 连接到 WPA/WPA2 PSK WiFi 网络

java - 我是否保证每个使用 JNI 的进程只有一个 JavaVM?