【问题标题】:How do I check if output stream of a socket is closed?如何检查套接字的输出流是否关闭?
【发布时间】:2011-02-06 03:25:34
【问题描述】:

我有这个代码:

public void post(String message) {
    output.close();
    final String mess = message;
    (new Thread() {
        public void run() {
            while (true) {
                try {
                    output.println(mess);
                    System.out.println("The following message was successfully sent:");
                    System.out.println(mess);
                    break;
                } catch (NullPointerException e) {
                    try {Thread.sleep(1000);} catch (InterruptedException ie) {}
                }
            }
        }
    }).start();
}

如您所见,我在代码的最开头关闭了套接字,然后try 使用它将一些信息发送到另一台计算机。程序写给我“以下消息已成功发送”。这意味着没有抛出 NullPointerException。

那么,如果 Java 尝试使用套接字的关闭输出流,它不会抛出异常吗?有没有办法检查套接字是关闭还是打开?

添加

我通过以下方式初始化套接字:

clientSideSocket = new Socket(hostname,port);
PrintWriter out = new PrintWriter(clientSideSocket.getOutputStream(), true);
browser.output = out;

【问题讨论】:

  • 输出的声明在哪里?它是如何初始化的?你的代码应该抛出的异常不是 NullPointerException 而是 IOException。
  • 我添加了用于初始化套接字的代码。 Andrea,你说应该抛出 IOException。但它不会被抛出。为什么?
  • 不知道。它应该来自 PrintWriter 源。我能想到的唯一问题是某种同步问题(您在一个线程中关闭编写器并在另一个线程中使用,可能在不同的核心中执行),但我并不是这个领域的专家。已编辑:尝试在线程内移动 PintWriter 的创建。
  • 如果您将output 成员变量声明为volatile,会发生什么?
  • @Andrea 该线程是在关闭输出的同一线程中创建的。保证 output.close() 在其他线程开始执行时完成。

标签: java sockets networking outputstream


【解决方案1】:

我应该看起来更好。来自 PrintWriter 的 javadoc:

此类中的方法从不抛出 I/O 例外,虽然它的一些 构造函数可能。客户可能 询问是否有任何错误 通过调用 {@link #checkError checkError()}。

【讨论】:

    【解决方案2】:

    (a) 不要在网络上使用 PrintStream 或 PrintWriter,因为它们会抑制异常。它们实际上仅用于日志文件或控制台,您不太关心。您正在通过网络参与协议,您需要立即了解故障。

    (b) Socket.isClosed() 如果您关闭了它的输入或输出,则返回 true。注意它不告诉你其他人是否关闭了连接 - 这不是它的功能。只有阅读 EOS 才能告诉你。

    【讨论】:

      猜你喜欢
      • 2011-04-26
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      • 2018-12-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多