我有一个输入流来自黑盒子(比方说B)。来自此流的所有消息都是序列化的二进制数据,每条消息都以一个四字节的int开头。其中大部分是记录数据,每天24小时运行。我使用readInt()方法读取这四个字节。现在,偶尔,主线程将以EOFException退出并使程序崩溃。
在研究了这个之后,我发现当readInt()时输入流中的字节少于4个字节时会发生这种情况。我的猜测是缓冲区在连续读取之间的填充速度不够快。我想到的一些可能的解决方案包括在读取之前检查available()(考虑数据的amt消耗太多周期)或在发生异常时重新启动(听起来像编程很差)。如果我能阻止使用readInt(),我认为这将是最好的方法。我已经看过了readInt()的实现,但是再次归结为使用read()进行阻塞。
任何人都知道更好的解决方案吗?
答案 0 :(得分:1)
我相信您正在使用DataInputStream。当它包装的流时,该类抛出EOFException,从read()方法返回-1(实际上阻塞直到输入数据可用)。
我想,您应该看看为什么主流的读取首先返回-1。
答案 1 :(得分:1)
调用层次结构中的任何阻塞调用都是“绑定”的,以使所有调用都链接阻塞,因为两个调用都是同一执行线程的一部分。 readInt
的{{1}}方法对基础输入流的DataInputStream
方法进行四次调用,只要数据不可用就肯定会阻塞,因此您担心“缓冲区不会” t填写得足够快“似乎不合逻辑。
在服务器进程死亡或丢弃连接的情况下,我遇到过这种异常,在这种情况下,客户端最终读取-1并抛出异常。您是否在客户端/服务器代码中吞噬任何类型的异常?您的日志是否显示任何可疑内容?
答案 2 :(得分:0)
基本的InputStream接口需要阻塞读取,当readInt()遇到流标记的结尾时,抛出你得到的EOFException,因为返回不完整的int会是一个坏主意,它会抛出 E nd O f F ile异常。
抛出EOFException因为流的另一端到达终点,已关闭或不再连接。您应该检查黑盒是否终止连接。
由于流是基于网络的,因此套接字可能有超时设置,如果是这种情况,请尝试更改套接字的SOTimeout值。