【问题标题】:ObjectInputStream and ObjectOutputStream对象输入流和对象输出流
【发布时间】:2009-11-22 22:39:02
【问题描述】:

我已经编写了一个 EchoServer,如果数据已被相应发送,它会以字符串 ack 进行响应。

我的客户端看起来像这样......为了从服务器接收 ack 应答,“echoSocket”将接收到的数据放入我的 ObjectInputStream。只有当我将这些部分注释掉时,客户才能工作

        echoSocket = new Socket(server_name, tcp_port);
        System.out.println(" *** Connected to " + server_name  + " ***");
        System.out.println("Press Enter to send your message.");

        out = new ObjectOutputStream(echoSocket.getOutputStream());
        in = new ObjectInputStream(echoSocket.getInputStream());

        out.flush();

        String message = System.console().readLine();

        while(!message.equals("quit")) {


            // problem                
            if (in.readObject().equals(ack)) 
                System.out.println("ACKed");
            in.close();
            // problem ends
            out.flush();

            out.writeObject(message);
            System.out.println("Sending: " + message);      
            message = System.console().readLine();
            out.flush();

        }

有人知道为什么它不会发送我的字符串吗?

谢谢, 马吕斯

【问题讨论】:

  • ack 是字符串文字吗?改为:if (in.readObject().equals("ack"))

标签: java sockets


【解决方案1】:

在套接字上使用对象流并不是一个真正推荐的想法。您可以考虑使用完整的 Web 服务或 RMI。

如果您读入缓冲区并确保在尝试使用对象流反序列化之前拥有整个业务,它可能会更好。

【讨论】:

  • RMI 非常昂贵。有时,流 + 套接字是更好的解决方案。
  • 如果您读入缓冲区,它不会工作得更好 - 然后您必须自己管理对象边界。但是插入 BufferedInputStream 将意味着对操作系统级读取系统调用的调用更少。由于尝试在同一线程中读取和写入同一通道时发生阻塞,这样的测试通常会失败。
【解决方案2】:

为什么不使用 hessian 库?

它就像一个魅力: http://karussell.wordpress.com/2009/04/10/hessian-web-service-protocol-hello-world-example/

或者尝试弹簧远程处理(不是那么轻量级)

http://static.springsource.org/spring/docs/2.5.x/reference/remoting.html

【讨论】:

    【解决方案3】:

    看起来客户端在写入消息之前试图读取确认。

    【讨论】:

    • 即使我改变了客户只是停止的顺序。响应是可选的……如果没有响应,它会一直等待。
    • readObject() 将阻塞直到接收到数据。因此,如果服务器从不确认,那么您将永远等待。您说 ACK 是可选的……如果不需要,也许您可​​以扩展为什么需要 ACK。在放弃之前你应该等待多久?为什么这个循环甚至关心?
    • @wishi_ 我建议你停止随意移动东西,想想发生了什么。正如@PSpeed 所说,对客户端的输入流调用读取操作将导致它阻塞,直到它从服务器接收到数据(可选或非可选)。
    【解决方案4】:

    将“发送”和“接收”代码拆分为单独的线程,写入器线程可以写入套接字,而您的其他线程在调用 readObject() 时被阻塞。

    如果这将是一个长期运行的客户端,我还建议使用较低级别的 DataInputStream 和 DataOutputStream 而不是 ObjectInputStream / ObjectOutputStream,以防止持有可能较大的对象 IdentityHashmap。

    【讨论】:

      猜你喜欢
      • 2017-05-19
      • 2013-11-14
      • 2014-07-22
      • 2011-02-21
      • 1970-01-01
      • 2019-10-03
      • 1970-01-01
      • 2015-03-21
      • 1970-01-01
      相关资源
      最近更新 更多