如何检查套接字的输出流是否已关闭?

3

I have this code:

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

正如您所看到的,我在代码开头关闭了套接字,然后尝试将一些信息发送到另一台计算机。程序会写入“以下消息已成功发送”。这意味着未抛出NullPointerException异常。
那么,如果尝试使用已关闭的套接字输出流,Java是否不会抛出任何异常?有没有办法检查套接字是关闭还是打开?
添加:
我以以下方式初始化套接字:
clientSideSocket = new Socket(hostname,port);
PrintWriter out = new PrintWriter(clientSideSocket.getOutputStream(), true);
browser.output = out;

2
输出的声明在哪里? 它是如何初始化的? 你的代码应该抛出的异常不是NullPointerException,而是IOException。 - Andrea Polci
我添加了用于初始化套接字的代码。Andrea,你说应该抛出IOException。但它没有被抛出。为什么? - Roman
不知道。从PrintWriter源代码来看应该是可以的。 我能想到的唯一问题是某种同步问题(您在一个线程中关闭写入器,在另一个线程中使用它,可能在不同的核心上执行),但我对这个领域并不是很专业。编辑:尝试将PintWriter的创建移动到线程内部。 - Andrea Polci
如果将output成员变量声明为volatile会发生什么? - Ash
@Andrea 线程是在关闭输出的相同线程中创建的。保证在其他线程开始执行时,output.close()已经完成。 - sfussenegger
@sfussenegger,就像我之前说的那样,我错了,这不是一个同步问题。 - Andrea Polci
2个回答

7

我应该仔细查看。从PrintWriter的javadoc中可以看出:

这个类中的方法永远不会抛出I/O异常,尽管它的一些构造函数可能会。客户端可以通过调用{@link #checkError checkError()}来查询是否发生了任何错误。


3
(a) 不要在网络上使用PrintStream或PrintWriter,因为它们会抑制异常。它们真正只适用于日志文件或控制台,您对此不太关心。在网络上,您正在参与协议,并且需要立即了解故障情况。
(b) Socket.isClosed()返回true,如果您关闭了其输入或输出的任何一个。请注意,它并不告诉您对方是否已关闭连接 - 这不是它的功能。只有读取EOS才能告诉您这一点。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接