【问题标题】:What happens when client closes connection before server is done reading bytes from BufferedInputStream?当客户端在服务器完成从 BufferedInputStream 读取字节之前关闭连接会发生什么?
【发布时间】:2021-07-18 03:23:21
【问题描述】:

我正在读取通过网络上传的文件,它通过 http 发送,我们通过 BufferedInputStream 接收。有时我们在从流中读取的过程中会遇到超时异常。我的工作理论是,在我们处理整个文件之前,连接已从客户端关闭。文件的顺序是mb。

这个理论有意义吗?客户端是否需要保持连接打开,以便服务器从输入流中完全读取字节?

【问题讨论】:

  • 如果客户端关闭,或者更确切地说,如果它半关闭上传方向,您的读取将获得 EOF,这取决于您使用的方法通常会返回一个特殊值(例如 read(byte[]) 返回 - 1, readLine() 返回 null) 但可能会抛出 EOFException,而不是 TimeoutException。因此,这不是您的情况。超时意味着客户端没有发送所有数据,或者它正在发送或网络在您设置的超时时间内传输数据太慢。关闭不会导致数据丢失; 中止可以,但在现代网络中不太可能。
  • 您能否使用您收到的确切错误消息(异常跟踪)以及您用于发送和接收文件的代码来更新问题?无论如何,服务器读取的超时将与连接的服务器端的超时设置有关,并且在数据流停止但连接仍然打开时触发。可能是客户端速度慢或在上传过程中失去网络访问权限

标签: java bufferedinputstream


【解决方案1】:

这个理论有意义吗?客户端是否需要保持连接打开,以便服务器从输入流中完全读取字节?

没有。

只要BufferedInputStream 缓冲区中有字节,对read() / read(byte[]) / read(byte[], int, int) 的任何调用都只会为您提供缓冲区中的数据,甚至不会触及底层输入流。

只要您不接触所述输入流,它就不能开始从晴朗的蓝天中抛出异常。您需要在实际的套接字输入流上调用 something(无论是读取、关闭、刷新、写入 - 一些东西),以便引发异常。

可能发生的是混合模式操作:您调用例如:

var raw = socket.getInputStream();
var buffered = new BufferedInputStream(raw);
byte[] b = new byte[1000];
buffered.read(b); // actually reads 4000 bytes into buffer, giving 1000 of them.
// 3000 left in the buffer!
byte[] c = new byte[2000];
buffered.read(c); // works fine and never touches raw. Can't throw.
byte[] d = new byte[2000];
buffered.read(d); // 'mixed mode'

这里,在'混合模式'的情况下,前1000个字节被缓冲区填充,然后raw.available()被调用(来源:BufferedInputStream.java的实际源代码);如果返回非零数,则直接从 raw 中获取更多数据;如果为 0,read() 只返回(read() 没有义务读取所有请求的字节;它只需要 [A] 读取至少 1,然后 [B] 返回它读取了多少;通常你想要readNBytes)。

但是,in.available() 允许投掷。如果是这样,瞧。

但是,正常的 TCP 关闭不会导致 TimeoutExceptions。

更可能的情况如下:您的代码处理数据的速度不够快。发送实体在某些时候只是厌倦了这一切,拒绝继续让您占用文件句柄并挂断您的电话。如果您已经在使用缓冲区,则可能是中间有一些网络设备速度很慢,或者服务器配置了对网络连接速度的不切实际的期望。

【讨论】:

    【解决方案2】:

    在那种情况下没有好消息,会发生数据丢失。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      • 1970-01-01
      • 2014-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多