Had*_*adi 6 java android inputstream limit download-speed
我使用以下代码来限制java中文件的下载速度:
package org;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
class MainClass {
public static void main(String[] args) {
download("https://speed.hetzner.de/100MB.bin");
}
public static void download(String link) {
try {
URL url = new URL(link);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(5000);
con.setReadTimeout(5000);
InputStream is = con.getInputStream();
CustomInputStream inputStream = new CustomInputStream(is);
byte[] buffer = new byte[2024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
System.out.println("downloaded : " + len);
//save file
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static class CustomInputStream extends InputStream {
private static final int MAX_SPEED = 8 * 1024;
private final long ONE_SECOND = 1000;
private long downloadedWhithinOneSecond = 0L;
private long lastTime = System.currentTimeMillis();
private InputStream inputStream;
public CustomInputStream(InputStream inputStream) {
this.inputStream = inputStream;
lastTime = System.currentTimeMillis();
}
@Override
public int read() throws IOException {
long currentTime;
if (downloadedWhithinOneSecond >= MAX_SPEED
&& (((currentTime = System.currentTimeMillis()) - lastTime) < ONE_SECOND)) {
try {
Thread.sleep(ONE_SECOND - (currentTime - lastTime));
} catch (InterruptedException e) {
e.printStackTrace();
}
downloadedWhithinOneSecond = 0;
lastTime = System.currentTimeMillis();
}
int res = inputStream.read();
if (res >= 0) {
downloadedWhithinOneSecond++;
}
return res;
}
@Override
public int available() throws IOException {
return inputStream.available();
}
@Override
public void close() throws IOException {
inputStream.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
下载速度成功受限,但出现了新问题.当下载正在进行中,并且我与互联网断开连接时,下载不会结束并持续一段时间.当我断开互联网连接时,抛出java.net.SocketTimeoutException异常需要10秒以上.我真的不明白后台会发生什么.
为什么会出现这个问题?
您的速率限制实际上并不像您想象的那样起作用,因为数据实际上并不是逐字节发送,而是以数据包的形式发送。这些数据包被缓冲,您观察到的(下载在没有连接的情况下继续)只是您的流读取缓冲区。一旦到达缓冲区末尾,它就会等待 5 秒,然后才会引发超时(因为这是您配置的)。
您将速率设置为 8 kB/s,正常数据包大小通常约为 1 kB,最大可达 64 kB,因此您将在 8 秒内仍在读取同一数据包。此外,可能已经发送并缓冲了多个数据包。还有一个接收缓冲区,该缓冲区可以小至 8 - 32 kB,大至数 MB。所以实际上你只是从缓冲区中读取。
[编辑]
只是为了澄清,你正在做正确的事。平均而言,费率将限制在您指定的范围内。服务器将发送一堆数据,然后等待客户端清空其缓冲区以接收更多数据。
| 归档时间: |
|
| 查看次数: |
666 次 |
| 最近记录: |