【问题标题】:Correct way to close a socket and ObjectOutputStream?关闭套接字和 ObjectOutputStream 的正确方法?
【发布时间】:2010-10-13 20:06:45
【问题描述】:

我正在用 Java 编写一个网络应用程序,以在客户端和服务器之间进行通信,我使用序列化对象来表示数据/命令并通过对象输出/输入流发送它们。

我在干净地关闭连接时遇到问题,我认为我错过了一些我不太了解的基本知识,我以前从未使用过带有序列化的套接字。

我尝试关闭连接(先关闭客户端,先关闭服务器)的任何命令都会引发ConnectionReset 异常。我无法捕获此异常,因为客户端在另一个线程中运行到程序的其余部分不断侦听消息,必须这样做,因为在 Java 中 socket.read() 是一种阻塞方法。

关闭我用来发送对象的套接字的正确方法是什么?

【问题讨论】:

标签: java networking sockets serialization


【解决方案1】:

ObjectInputStream.readObject() 将抛出 EOFException 如果对等方已完成发送对象并关闭连接。你肯定忽略了它。

【讨论】:

    【解决方案2】:

    您可以通过 TCP/IP 协议实现您的协议。使用该协议的数据包的头部分将表示不同类型的数据包,如连接数据包、数据包、关闭连接数据包等。

    【讨论】:

    • 呃,不,他正在使用序列化。
    【解决方案3】:

    您需要向您的侦听器(无论是客户端还是服务器,都无所谓)发送某种信号以停止侦听更多数据。这是一个非常简单的例子:

    ObjectInputStream ois = new ObjectInputStream(new BufferedInputStream(sock.getInputStream()));
    
    while (true) {
        Object obj = ois.readObject();
    
        if (obj instanceof String) {
            if ((String)obj).equalsIgnoreCase("quit")) {
                break;
            }
        }
    
        // handle object
    }
    
    ois.close();
    sock.close();
    

    【讨论】:

    • 谢谢,我从没想过要通知我的程序退出,我猜 TCP 会这样做。我认为正如 Avi 所说,我在关闭套接字时正在等待输入,通过提醒客户端我可以告诉它停止等待输入。
    • 你不需要关闭ObjectInputStream,文档告诉:Closing this socket will also close the socket's InputStream and OutputStream.
    【解决方案4】:

    您可能不应该等待从套接字读取(),而另一端正在关闭它。在一个好的网络协议中,客户端可以在关闭连接之前通知服务器它没有更多的东西可写(可能通过向它发送一个特殊的关闭字符)。

    【讨论】:

      猜你喜欢
      • 2017-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 2012-02-10
      • 2018-12-14
      • 1970-01-01
      相关资源
      最近更新 更多