【问题标题】:How to make readInt() block on input byte stream?如何在输入字节流上制作 readInt() 块?
【发布时间】:2011-06-20 17:11:38
【问题描述】:

我有一个来自黑盒(比如 B)的输入流。来自该流的所有消息都是序列化的二进制数据,每条消息都以一个四字节 int 开头。其中大部分是记录数据,每天 24 小时运行。我使用 readInt() 方法读取了这四个字节。现在,偶尔,主线程会以 EOFException 退出并使程序崩溃。

经过研究,我发现它发生在readInt()时输入流中少于四个字节的情况下。我的猜测是缓冲区在连续读取之间的填充速度不够快。我正在考虑的一些可能的解决方案包括在读取之前检查 available() (考虑到数据量会消耗太多周期)或在发生异常时重新启动(听起来像是糟糕的编程)。如果我能阻止使用 readInt(),我认为这将是最好的方法。我已经查看了 readInt() 的实现,但它再次归结为使用 read() 阻塞。

有人知道更好的解决方案吗?

【问题讨论】:

  • 您似乎通过生成文字墙来阻止阅读流程;-) 引入一些段落可能会使这更具可读性(并有助于获得答案)。
  • 您从哪种流中读取?
  • 你说得有道理,约阿希姆。我会更加小心。我正在使用 Stas 猜测的 DataInputStream。在另一端有一个嵌入式设备使得在那里改变东西变得困难。我的猜测是,黑盒可能会间歇性地发送字节块,而不关心消息是否完整发送。流有时可能会干涸而没有完整的内容。

标签: java exception-handling tcp network-programming stream


【解决方案1】:

调用层次结构中的任何阻塞调用都被“绑定”以使链上的所有调用都阻塞,因为这两个调用都是同一执行线程的一部分。 DataInputStreamreadInt 方法对底层输入流的 read 方法进行了四次调用,只要数据不可用,这肯定会阻塞,因此您担心“缓冲区填充不够快”似乎不合逻辑。

在服务器进程死亡或断开连接的情况下,我遇到过此类异常,在这种情况下,客户端最终读取 -1 并引发异常。您是否在客户端/服务器代码中吞噬了任何类型的异常?您的日志是否显示任何可疑内容?

【讨论】:

  • 您对阻止的看法是正确的。在我的例子中,服务器是一个嵌入式设备,可能会间歇性地发送数据块。当流中的东西不可用时,read() 返回 -1 并且 readInt() 返回 EOFException。这是预期的行为。有没有办法绕过这个?
  • 可以假设数据永远不会停止流动,我不担心关闭流。因此,出于实际目的,可以假设连接永远不会在服务器端关闭,并且永远不会到达流的实际结束。
  • 就像已经提到的那样,没有“当流中的东西不可用时”,因为只要服务器不决定返回-1,客户端就会“等待”。由于来自服务器的这些数据是流式的,并且以块的形式流动,您是否确保为您的客户端/服务器套接字设置了适当的超时时间?
【解决方案2】:

我相信您正在使用 DataInputStream。该类在其包装的流从 read() 方法返回 -1 的情况下抛出 EOFException(实际上阻塞直到输入数据可用)。

我想,你应该看看为什么主流的读取首先返回 -1。

【讨论】:

    【解决方案3】:

    基本的InputStream 接口需要阻塞读取,当 readInt() 遇到流结束标记时会抛出 EOFException,因为返回不完整的 int 将是一个坏主意,它会抛出 End Of File Exception.

    EOFException 被抛出,因为流的另一端已到达其末尾,已关闭或不再连接。您应该检查黑盒是否终止连接。

    由于流是基于网络的,您的套接字可能设置了超时,如果是这种情况,请尝试更改套接字的 SOTimeout 值。

    【讨论】:

    • 黑匣子是嵌入式设备,可能会发送间歇性数据块。这可能会导致另一端只有
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 2021-07-04
    • 2012-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多