Java Socket读取大数据遇到间歇性错误

时间:2010-12-07 09:47:35

标签: java sockets download

我正在开发一个通过套接字与第三方应用程序通信的应用程序。基本上,我的应用程序需要向服务器发送一些请求,服务器返回一些数据。当服务器向我发回少量数据时,一切运行良好。但是,当我从服务器请求大量数据时,我的应用程序有时不会收到完整的数据,而是间歇性地发生。

我已经在互联网上做了一些研究,并按照我发现的套接字编程示例,但仍然无法解决问题。以下是我目前的实施情况。

     BufferedInputStream is = new BufferedInputStream(socket.getInputStream());

    //I know the size of data that I am expecting from the server
    byte[] buffer = new byte[length];

    int count = 0;
    int current = 0;

    while(count < length) {
        current = is.read(buffer, count, length - count);

        if(current == -1) {
            break;
        } else {                
            count += current;
        }          
    }

我知道我期望从服务器获取的数据大小。出现问题时,read()方法在从服务器完全接收数据之前返回-1。我没有任何访问服务器端实现的权限。如果我错过了我的代码或者有更好的方法,请告诉我。

3 个答案:

答案 0 :(得分:3)

如果read方法返回-1,则服务器在发送任何发送的内容后关闭了套接字。期。如果您期待更多数据,那就错了。

服务器可能编码错误,例如关闭其套接字而不是其最外面的输出流,从而丢失数据。或者可能你的结局是不正确的,例如通过为每个套接字创建多个BufferedInputStreams,而不是套接字的生命周期。

您的代码只是复制DataInputStream.readFully()。但是你应该做的是处理收到的每个缓冲区加载,而不是尝试在内存中创建任意大的缓冲区。这只会浪费空间并增加延迟。

答案 1 :(得分:1)

您的代码看起来基本上是合理的。 (在这种情况下,使用BufferedInputStream并不能提高性能。如果有的话,它会使速度变慢。但是,这不太可能导致这个问题。)

在客户端内存中缓冲大量内容也可能导致客户端无响应长时间导致套接字超时。但是,如果你的文件大小只有几兆字节,你可以放弃这种可能性。

但是,我怀疑真正的问题是客户端或服务器端的套接字超时太小。但如果您无法访问服务器端配置和日志,则很难诊断出来。

答案 2 :(得分:0)

您的代码中存在一些严重问题:

假设长度= 8GB

创建这样大小的byte []会遇到很多问题。

int count
int current

这应该是

long count
long current

但如果你这样做,代码将不再编译。所以你有一个Integer.MAX_VALUE的最大文件大小。如果您将下载存储到bytearray。 (感谢EJP)

您必须将该数据写入除RAM之外的其他内存中的文件。使用32位JVM,您永远不会创建大于~1.3 GB的byte []。