HttpURLConnection.getInputStream 很慢
Posted
技术标签:
【中文标题】HttpURLConnection.getInputStream 很慢【英文标题】:HttpURLConnection.getInputStream very slow 【发布时间】:2013-06-30 15:49:58 【问题描述】:与使用相同服务器端服务的 iPhone App 相比,HttpURLConnection.getInputStream 需要非常多的时间。
以下代码用于服务:
date= new java.util.Date();
Log.d("time","Time Stamp before posting "+new Timestamp(date.getTime()));
URL ur= new URL(url);
HttpURLConnection conn = (HttpURLConnection) ur.openConnection();
conn.setRequestProperty("Connection", "close");
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(getQuery(nameValuePairs));
writer.close();
os.close();
conn.connect();
StringBuffer response=null;
try
Log.d("time","Time Stamp bfr InputStream "+new Timestamp(date.getTime()));
InputStream is = conn.getInputStream();
date= new java.util.Date();
Log.d("time","Time Stamp aftr InputStream "+new Timestamp(date.getTime()));
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
response = new StringBuffer();
while((line = rd.readLine()) != null)
response.append(line);
response.append('\r');
rd.close();
response.toString();
result=response.toString();
catch (Exception e)
为了检查服务在哪里花费时间,我将日志条目打印为时间戳。
该过程的平均时间如下:
发布到服务器的平均时间不到 2 百万秒 创建输入流的平均时间大约需要 5 秒
写入响应的平均时间小于 2 百万秒。
知道为什么输入流需要很长时间,从而导致整个服务非常慢吗?
【问题讨论】:
【参考方案1】:你没有衡量你认为你正在衡量的东西。在您调用 getInputStream() 或 getResponseCode() 之前,没有任何内容会写入服务器。所以你真的在测量:
连接时间 传输时间 服务器处理时间当你认为你只是在测量 getInputStream() 时间时。
原因是 HttpURLConnection 通过缓冲所有输出来自动设置内容长度标头。您可以通过使用分块传输模式来避免这种情况。那么至少你会看到时间到底在哪里。
【讨论】:
我们该怎么做?【参考方案2】:这可能与 JDK 7 中引入的错误有关。“HttpServer 在使用 keep-alive 缓存时会产生 1000 毫秒的延迟”。见:
http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8009548
根据您的目的,建议的解决方法是多线程处理 HttpUrlConnection。例如,如果您使用的是 HttpServer,您可以这样做:
server.setExecutor( Executors.newFixedThreadPool( 5 ) );
【讨论】:
仅当他在另一端使用HttpServer
时。没有证据。建议的解决方法是多线程服务器,这又是无关紧要的。【参考方案3】:
将 urlConnection.setConnectTimeout() 设置为较低的超时时间。
URLConnection.setConnectTimeout() 的类文档说:
设置连接时等待的最长时间(以毫秒为单位)。如果在建立连接之前超时已过,则连接到服务器将失败并返回 SocketTimeoutException。默认值 0 导致我们进行阻塞连接。这并不意味着我们永远不会超时,但它可能意味着您将在几分钟后获得 TCP 超时。
警告:如果主机名解析为多个 IP 地址,这 客户端将按 RFC 3484 顺序尝试每个。如果连接到其中的每一个 地址失败,在连接之前会经过多次超时 尝试抛出异常。同时支持 IPv6 和 IPv4 始终至少有 2 个 IP 地址。
我最初将我的设置为urlConnection.setConnectTimeout(30000);
,然后将其更改为urlConnection.setConnectTimeout(1000)
。立即,我看到了更快的结果。
希望这会有所帮助!
【讨论】:
你的意思是你看到更快的连接失败,当你得到它们时。很难看出这如何解决 OP 的问题。 这很奇怪,但它有效!也许 while 循环会永远循环或其他什么,但对我来说,这个答案非常有效!以上是关于HttpURLConnection.getInputStream 很慢的主要内容,如果未能解决你的问题,请参考以下文章