我有一个 Java 程序,它接受连接、接收 HTTP 请求并发送 HTTP 回复以及存储在文件中的一些数据(这是缓存代理的一部分)。删除所有不相关的内容,我的代码如下所示:
FileInputStream fileInputStream = new FileInputStream(file);
OutputStream outputStream = socket.getOutputStream();
byte[] buf = new byte[BUFFER_SIZE];
int len = 0;
while ((len = fileInputStream.read(buf)) > 0) {
outputStream.write(buf, 0, len);
}
outputStream.flush();
socket.close();
该代码在每个连接的客户端的特定线程中执行。
当我处理小文件(.htm、.gif、.swf 等)时,一切正常(但是,我在浏览器中没有看到任何问题)。但是,当我下载大文件(.iso)时,尤其是同时下载多个文件时,当系统处于负载状态时,有时我会遇到非常奇怪的行为。浏览器下载文件的 99.99%,当未下载字节数小于 BUFFER_SIZE 时,下载会停止几秒钟,然后浏览器会提示发生错误。我无法理解发生了什么,因为all数据读取成功,甚至all数据已成功写入outputStream。正如你所看到的,我什至做了flush(),但它没有结果。
谁能解释一下发生了什么?
EDIT
已将项目上传到 filehosting.org。
下载源文件 http://www.filehosting.org/file/details/87679/Proxy.zip。有包含源代码、Build.xml 和 Readme.txt 的 zip 存档。使用ant构建解决方案。所描述的问题出现在 ClientManager.java 中,您会在那里找到注释。
基于对 JDK 1.6 代码库的快速搜索:
-
socket.getOutputStream()
返回一个SocketOutputStream
实例
-
flush()
确实没有影响SocketOutputStream
实例
-
write()
on a SocketOutputStream
实例似乎没有缓冲 Java 代码中的任何内容
-
shutdownOutput()
应确保在关闭套接字的输出端之前写入所有未完成的数据。至少,评论是这么说的。
然而,一些 Socket 等实现是本机方法,我没有深入研究。
据我所知,“正确”的顺序是:
socket.shutdownOutput();
socket.close();
然而,你说你已经尝试过了。另一端的应用程序是否可能提前关闭 TCP/IP 连接?
另一个想法:你试过了setSoLinger(true, 60000)
,但 60000 秒可能比操作系统允许的更长。尝试setSoLinger(true, 60)
,并在打开输出流之前尝试执行此操作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)