4

我正在 Android 上解决这个问题,但这不是 Android 特有的问题。

使用 org.apache.http.client.HttpClient,我可以向大小为 1kb 的 URL 发出请求,整个响应包含在 HttpResponse 中:

HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://10.16.83.67/1kb.log");
HttpResponse response = null;
BufferedReader rd = null;

response = client.execute(request);

然后我可以从响应中获取 HttpEntity:

HttpEntity entity = response.getEntity();
rd = new BufferedReader(new InputStreamReader(entity.getContent()));

然后,使用 BufferedReader ...

while ((line = rd.readLine()) != null) {
 // ... parse or whatever
}

我正在看 WireShark,我看到上面代码的每个方向都有一个传输:对日志文件的请求,然后整个日志在响应中传递。

但是,如果我请求更大的东西,比如我的 1MB 日志文件,我会看到一些非常不同的东西。 数据被分块成帧,然后通过环路内的线路传输。rd.readLine()

在此处输入图像描述

似乎第一个 kb 左右包含在初始响应中。但是在readLine()运行时,它会向服务器发出额外的请求,并将数据流式传输到套接字。如果网络连接中断,我会收到 IO 错误。对于大型请求,entity.isStreaming()true.

这是一个异步调用(在 Android 上是强制性的,因为无法在 UI 线程上进行网络调用)但我不想继续,直到我确定我已完成从该请求接收所有数据。不幸的是,简单地等待一段时间,然后继续并希望得到最好的结果,这不是一种选择。

我的问题是:我HttpClient的 、HttpGetHttpResponseHttpEntity对象是否知道它们何时完成从该请求接收数据?还是我必须依靠 BufferedReader 才能知道流何时关闭?

4

2 回答 2

2

你在使用 AsyncTask 吗?否则你可以去这个

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
 protected Long doInBackground(URL... urls) {}

// 在上面的方法中做所有的http请求

 protected void onProgressUpdate(Integer... progress) {
     setProgressPercent(progress[0]);
 }

 protected void onPostExecute(Long result) {
     showDialog("I pop up when all the code in the DoInbackground is finished");
 }

}

于 2013-05-22T21:19:52.253 回答
1

你用的是什么httpclient?你可能想评估一下。

有很好的 httpclient 库允许使用这样的东西

请注意 3X 中的此示例。我使用 4X 并且没有要发布的任何分块响应代码。

如果你想寻找新的选择,你可以在这里查看

于 2013-05-23T00:18:31.220 回答