套接字关闭问题 - 最后一部分数据丢失 [英] Socket closing problem - last portion of data is lost

查看:209
本文介绍了套接字关闭问题 - 最后一部分数据丢失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Java程序,它接受连接,接收HTTP请求并发送HTTP回复和存储在文件中的一些数据(这是缓存代理的一部分)。删除所有不相关的内容,我的代码如下所示:

I have a Java program that accepts connections, receives HTTP requests and sends HTTP replies and some data stored in file (this is a part of caching proxy). Removing everything irrelevant, my code looks like this:

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();

此代码在每个连接的客户端的特定线程中执行。

This code is executed in particular thread for each connected client.

当我处理小文件(.htm,.gif,.swf等)时,一切正常(但是,我在浏览器中没有看到任何错误)。但是当我下载大文件(.iso),特别是同时下载几个文件时,当系统处于负载状态时,有时我会得到非常奇怪的行为。浏览器下载99.99%的文件,当下载的字节少于BUFFER_SIZE时,下载会停止几秒钟,然后浏览器会说错误已经发生。我无法理解会发生什么,因为所有数据都已成功读取,甚至所有数据也成功写入outputStream。正如你所看到的,我甚至做了flush(),但它没有结果。

When I deal with small files (.htm, .gif, .swf, etc.), everything works fine (however, I don't see anything wrong in browser). But when I download large files (.iso), especially several files simultaneously, when system is under load, sometimes I get really strange behavior. Browser downloads 99.99% of a file and when there are less than BUFFER_SIZE of undownloaded bytes, downloading stops for a few seconds and then browser says that error has occured. I can not understand what happens, because all data is successfully read and even all data is successfully written to outputStream. As you can see, I even do flush(), but it takes no result.

有人可以解释一下会发生什么吗?

Can anyone explain me what happens?

编辑

将项目上传到filehosting.org。

下载源文件。有zip源存档,包含源代码,Build.xml和Readme.txt。使用ant构建解决方案。在ClientManager.java中发生了描述的问题,你会在那里找到一个评论。

EDIT
Uploaded project to filehosting.org.
Download source files. There is zip archive with source code, Build.xml and Readme.txt. Use ant to build solution. Described problem occurs in ClientManager.java, you'll find a comment there.

推荐答案

基于快速浏览JDK 1.6 codebase:

Based on a quick trawl through the JDK 1.6 codebase:


  • socket.getOutputStream()返回 SocketOutputStream instance

  • flush()确实对 SocketOutputStream没有影响 instance

  • 上写一个() SocketOutputStream 实例似乎没有缓冲Java代码中的任何内容

  • shutdownOutput()应确保在关闭输出之前写入任何未完成的数据插座的一侧。至少,评论说明了。

  • socket.getOutputStream() returns a SocketOutputStream instance
  • flush() indeed has no effect on a SocketOutputStream instance
  • write() on a SocketOutputStream instance does not seem to buffer anything in Java code
  • shutdownOutput() should ensure that any outstanding data is written before shutting down the output side of the socket. At least, the comments say that.

然而,一些Socket等实现是本机方法,我没有深入研究那个。

However, some of the Socket etc implementation is native methods, and I didn't delve into that.

根据我的判断,正确序列将是:

Based on what I could tell, the "correct" sequence would be:

socket.shutdownOutput();
socket.close();

但是,你说你已经尝试过了。另一端的应用程序是否可能提前关闭TCP / IP连接?

However, you say you've tried that. Is it possible that the application at the other end is closing the TCP/IP connection early?

另一个想法:你试过 setSoLinger(true,60000) ),但操作系统允许的60000秒可能更长。尝试 setSoLinger(true,60),并在打开输出流之前尝试执行此操作。

Another thought: you tried setSoLinger(true, 60000), but 60000 seconds is possibly longer that the OS allows. Try setSoLinger(true, 60), and try doing it before you open the output stream.

这篇关于套接字关闭问题 - 最后一部分数据丢失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆