【问题标题】:Reading from SSL socket that has been closed by the server从已被服务器关闭的 SSL 套接字读取
【发布时间】:2014-09-24 23:54:30
【问题描述】:

我正在尝试通过 Java 客户端使用服务(Apple 的推送通知)。他们的文档指出,如果他们收到的数据有错误,他们会将一些错误代码写入套接字,然后将其关闭。 (在出现错误之前不返回任何内容。)

我有一个带有输入和输出流的 SSLSocket。我的代码写入输出流,直到它得到一个损坏的管道异常,然后尝试从输入流中读取。我从来没有看到任何返回的数据——就好像他们没有写承诺的错误代码就关闭了套接字。

在输出流上发生损坏的管道异常后,Java SSLSocket 实现中是否存在无法从套接字读取的内容(即 getInputStream() 的结果)?我没有关闭套接字输入或输出,或类似的东西。

还有其他想法吗?

我的代码如下所示:

SSLSocket socket = createMyConnectionToServer();

OutputStream outputStream = socket.getOutputStream();
InputStream inputStream = socket.getInputStream();
try {
    while (true) {
        outputStream.write(someStuff); // fails with broken pipe the second time
        outputStream.flush();
    }
} catch (SocketException ex) {
    while (true) {
        int b = inputStream.read();
        if (b == -1)
            break
        System.out.println("response " + b); // this never happens
    }
}

【问题讨论】:

    标签: java sockets ssl


    【解决方案1】:

    一直写到一个损坏的管道异常已经是错误的。一旦它坏了,你就不能读也不能写。这与 SSL 无关:明文套接字的行为方式相同。您可能需要一个单独的阅读线程。

    【讨论】:

    • 我认为这可行的原因是 Apple 的文档说“如果您发送的通知格式错误或无法理解,APNs 会返回一个错误响应数据包并关闭连接。”。我假设如果他们写然后关闭,我将能够阅读他们写的内容。第二个线程会引入竞争条件,但有时可能会起作用。
    • 你可以,但你必须阅读响应之前写入到打破管道的地步。我必须说我从来没有能够用这个协议来了解苹果的意图。他们应该承认所有事情,而不仅仅是错误。
    • 显然他们希望最大限度地减少服务器上的负载。他们可以通过(1)为好的数据包编写确认消息来修复他们的协议,或者,可能更重要的是,(2)编写错误消息并等待发送者关闭套接字。发生错误后,他们可以忽略所有后续数据,因为发件人应该能够备份到错误消息之后的第一条消息。
    • 同意。问题是该协议使客户端很难实现。您需要一个始终在读取、查找错误的线程,并且您需要它能够在出现错误时停止或向事物的写入端发出信号。在 TCP 的本质中,写入端可以轻松地在导致错误的写入之前获得一些写入,这会给您带来事务/回滚问题。
    猜你喜欢
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-21
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    相关资源
    最近更新 更多