我有一个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,len);
}
outputStream.flush();
socket.close();
此代码在每个连接的客户端的特定线程中执行.
当我处理小文件(.htm,.gif,.swf等)时,一切正常(但是,我没有看到浏览器中的任何错误).但是当我下载大文件(.iso),特别是同时下载几个文件时,当系统处于负载状态时,有时我会遇到很奇怪的行为.浏览器下载99.99%的文件,当下载的字节少于BUFFER_SIZE时,下载停止几秒钟,然后浏览器说出错.我无法理解会发生什么,因为所有数据都已成功读取,甚至所有数据都成功写入outputStream.正如你所看到的,我甚至做了flush(),但它没有结果.
谁能解释一下会发生什么?
编辑
将项目上传到filehosting.org.
Download source files.有zip源存档,包含源代码,Build.xml和Readme.txt.使用ant构建解决方案.在ClientManager.java中发生了所描述的问题,您可以在那里找到评论.
> socket.getOutputStream()返回SocketOutputStream实例
> flush()确实对SocketOutputStream实例没有影响
> SocketOutputStream实例上的write()似乎没有缓冲Java代码中的任何内容
> shutdownOutput()应确保在关闭套接字的输出端之前写入任何未完成的数据.至少,评论说.
但是,一些Socket等实现是本机方法,我没有深入研究.
根据我的判断,“正确”序列将是:
socket.shutdownOutput();
socket.close();
但是,你说你已经尝试过了.另一端的应用程序是否可能提前关闭TCP / IP连接?
另一个想法:你试过setSoLinger(true,60000),但操作系统允许的60000秒可能更长.尝试setSoLinger(true,60),并在打开输出流之前尝试执行此操作.