【问题标题】:Why is the download speed different between HttpURLConnection and HttpsURLConnection?为什么 HttpURLConnection 和 HttpsURLConnection 的下载速度不同?
【发布时间】:2014-11-18 03:15:37
【问题描述】:

我正在使用HttpURLConnectionHttpsURLConnection 下载内容。我的问题是为什么HttpURLConnectionHttpsURLConnection?之间的下载速度不同

这是一个sn-p:

if (downloadurl.startsWith("https://")) {
   HttpsConn = (HttpsURLConnection) url.openConnection();
   HttpsURLConnection.setDefaultHostnameVerifier(new AllowAllHostNameVerifier());       

    SSLContext sc;
                sc = SSLContext.getInstance("TLS");
                sc.init(null, new TrustManager[] {
                          new X509TrustManager() {
                                public void checkClientTrusted(X509Certificate[] chain, String authType) {}
                                public void checkServerTrusted(X509Certificate[] chain, String authType) {}
                                public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; }
                              }
                            }, null);
                HttpsConn.setSSLSocketFactory(sc.getSocketFactory());
   HttpsConn.setSSLSocketFactory(sc.getSocketFactory());

   HttpsConn.setConnectTimeout(CONNECT_TIME_SECONDS * 1000);
   HttpsConn.setReadTimeout(READ_TIME_SECONDS * 1000);
   HttpsConn.setChunkedStreamingMode(0);  
   HttpsConn.connect();
} else {
   URLConn = (HttpURLConnection) url.openConnection();
   URLConn.setConnectTimeout(CONNECT_TIME_SECONDS * 1000);
   URLConn.setReadTimeout(READ_TIME_SECONDS * 1000);
   URLConn.setChunkedStreamingMode(0);  
   URLConn.connect();
}               

                                   .
                                   .
                                   .

byte data[] = new byte[1048576];
double currentDownloadSize = 0.0;
long startTime = System.currentTimeMillis();
lastUpdateTime = startTime;
int count;

while ((count = input.read(data)) != -1) {
    currentDownloadSize += count;
    output.write(data, 0, count);
        Thread.sleep(10);

    if (isCancelled()) {
        output.flush();
        output.close();
        input.close();
    }
}

output.flush();
output.close();
input.close();

我用HttpURLConnection下载文件的时候下载速度还可以,但是用HttpsURLConnection的时候下载速度非常非常慢。我以为重点是inputStream!由于InputStream 的缓冲区大小取决于我在使用HttpURLConnection 时分配的字节大小,因此下载速度更快,因为它花费更少的时间将缓冲区数据写入文件。但是我用HttpsURLConnection的时候每次循环总是只有8000字节,下载速度有点可怕。

有人有想法吗?

【问题讨论】:

    标签: android inputstream outputstream httpsurlconnection


    【解决方案1】:

    首先摆脱sleep()。这简直就是浪费时间。它所做的只是放大较小读取的效果,您肯定会通过 HTTPS 获得这种效果,因为 TLS 块大小限制约为 16k。 flush() close() 之前的 close() 也是多余的,并且您在取消时没有正确地跳出循环。将循环更改为:

    while ((count = input.read(data)) != -1) {
        currentDownloadSize += count;
        output.write(data, 0, count);
    
        if (isCancelled()) {
            break;
        }
    }
    output.close();
    input.close();
    

    ...如果可能,不要在循环中做任何其他事情。

    设置分块流模式只会影响您将请求写入连接的方式。因为你不写任何东西,这也是没有意义的。

    我不知道您所说的“InputStream 的缓冲区大小...取决于我在使用 HttpURLConnection 时分配的字节大小”是什么意思。它没有。 InputStream 中没有缓冲区,除非它是 BufferedInputStream,而且您根本没有“分配”任何“字节大小”,除非您指的是 byte [] 缓冲区,它在任何意义上都不属于InputStream

    您的标题与问题的主体不符。

    【讨论】:

    • 感谢您的分享。您对如何一次阅读 16k 左右有什么建议吗?
    • 你问错问题了。您无法控制每次读取可用的数据量或 SSL 的速度。您要做的就是尽可能快地阅读到达的任何内容。将睡眠和其他代码添加到读取循环中不会实现这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 2018-11-08
    • 2017-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多