6

我现在才刚刚开始涉足 HTTP。我一直在使用 GET 和 POST 来计时简单的 HTTP 请求。我使用的网页是 3 行 php 检查正确的 $_GET[] 和 $_POST[] 然后简单地回显字符“1”。我使用具有相同的单个短名称/值对的 POST 和 GET,希望不需要数据包碎片来搞砸事情,所有这些都是在脱离 UI 线程的线程上完成的。这些请求在计时时会在电话上循环几次。一切正常。(见下面的代码)也就是说,我得到了“1”的响应。但存在一个持续存在的时间问题。我观察到的是:

  1. 在第一次尝试中发出请求的时间比在 GET 和 POST 方法中的后续尝试要长得多。

  2. 其余的尝试对两者来说总是快得多。

  3. GET 总是比 POST 快。

所有这些都适用于 3G 和 Wifi 连接(但总体而言,Wifi 速度比预期的要快得多)。

我已经用 BasicResponseHandler() 和更多的手动缓冲 IO 流方法进行了尝试,结果相同。

我相信我理解 3. 因为 POST 需要两次传输,一次用于“HTTP 100”返回,然后是数据包主体。- 这个对吗?

我的主要问题是第一次请求尝试如此缓慢时发生了什么?有时需要几秒钟(!)。是网络阻止了事情还是Android将其放入了某种套接字创建队列?如果是 Android,有没有办法更正确地编码并避免这种情况?是否有一些关于保持套接字打开以使这个问题在执行期间仅出现一次?如果是这样,这样做是个好习惯吗?诚然,我对此一无所知。

我已经找到了一些关于这个的讨论,但没有一个直接触及这个方面。

--

GET 和 POST 方法的基本代码如下所示(减去 try/catch),并且在 UI 之外的线程中执行,首先是 GET 方法,然后是 POST 方法:(下面的输出)

获取其中的一部分:

public String[] HTTPGETIt(int numrounds)
{
 HttpClient httpclient = new DefaultHttpClient();
 httpclient.getParams().setParameter (CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
 HttpGet GETRequest = new HttpGet("http://mypage.com/epoch.php?mynameis=tam");
 ResponseHandler <String> MyBRH = new BasicResponseHandler();
 String[] GETResult = new String[numrounds];

 int i = 0;
 long timestart, DT;
 while(i < numrounds)
 {
  timestart = System.currentTimeMillis();
  GETResult[i] = httpclient.execute(GETRequest, MyBRH);
  DT = System.currentTimeMillis() - timestart;
  Log.d(TAG, "(" + i + ") GET-Round Trip was "+ DT + " ms.");
  i++;
 }//while i <= numrounds
 httpclient.getConnectionManager().shutdown();
 return GETResult;
} //END HTTPGETIt

和 POST 版本:

public String[] HTTPPOSTIt(int numrounds)
{
 String Place = "HTTPPostping";
 HttpClient httpclient = new DefaultHttpClient();
 httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); 
 HttpPost PostRequest = new HttpPost("http://mypage.com/epoch.php");
 ResponseHandler <String> MyBRH = new BasicResponseHandler();
 String[] POSTResult = new String[numrounds];

 List<NameValuePair> MynameValuePairs = new ArrayList<NameValuePair>(2);
 MynameValuePairs.add(new BasicNameValuePair("mynameis", "tam"));

 PostRequest.setEntity(new UrlEncodedFormEntity(MynameValuePairs));

 int i = 0;
 long timestart, DT;
 while(i < numrounds)
 {
  timestart = System.currentTimeMillis();
  POSTResult[i] = httpclient.execute(PostRequest, MyBRH);
  DT = System.currentTimeMillis() - timestart;
  Log.d(TAG, "(" + i + ") POST-Round Trip was "+ DT + " ms.");
  i++;
 }//while i <= numrounds
 httpclient.getConnectionManager().shutdown();
 return POSTResult;
} // END HTTPPOSTIt

这些被调用:

Runnable HTTPGETJob = new HTTPGETTask(NS);
Thread HTTPGETThread = new Thread(HTTPGETJob, "HTTPGETThread");
HTTPGETThread.setPriority(Thread.MAX_PRIORITY);
HTTPGETThread.start();

和:

Runnable HTTPPOSTJob = new HTTPPOSTTask(NS);
Thread HTTPPOSTThread = new Thread(HTTPPOSTJob, "HTTPPOSTThread");
HTTPPOSTThread.setPriority(Thread.MAX_PRIORITY);
HTTPPOSTThread.start();

使用可运行文件:

class HTTPGETTask implements Runnable
{
 int numtimes;
 DeviceInfo tsrtDI;
 HTTPGETTask(int inNS) {
  this.numtimes = inNS;
 }

 @Override
 public void run() 
 {
  long [] TT2NS = new long[numtimes];
  TT2NS = HTTPGETIt(numtimes);
 }
};

和,

class HTTPPOSTTask implements Runnable
{
 int numtimes;
 DeviceInfo tsrtDI;
 HTTPPOSTTask(int inNS) {
  this.numtimes = inNS;
 }

 @Override
 public void run() 
 {
  long [] TT2NS = new long[numtimes];
  TT2NS = HTTPPOSTIt(numtimes);
 }
};  

输出通常是:

(0) GET-Round Trip 为 368 毫秒。

(1) GET-Round Trip 为 103 毫秒。

(2) GET-Round Trip 为 98 毫秒。

(3) GET-Round Trip 为 106 毫秒。

(4) GET-Round Trip 为 102 毫秒。


(0) POST-Round Trip 为 1289 毫秒。

(1) POST-Round Trip 为 567 毫秒。

(2) POST-Round Trip 为 589 毫秒。

(3) POST-Round Trip 为 496 毫秒。

(4) POST-Round Trip 为 557 毫秒。

4

2 回答 2

1

我会坚持你设置Protocol VersionHTTP 1.1并试一试。它会比现在增加请求/响应时间。不过我没试过,只是得到了信息。因此,您可以在执行请求之前尝试以下操作。

httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                                                        HttpVersion.HTTP_1_1);
于 2012-06-13T05:06:41.987 回答
1

我同意 Lalit Poptani 的回答,这可能有助于加快通话速度,因为 HTTP 1.1 保持连接并且每次都不会握手。

但同时,我想说这不是 Android 特有的问题,几乎每个平台和每种语言都会发生同样的事情,因为当您第一次进行任何 http 调用时,平台需要创建和设置不同的对象为它分配值以执行调用,并保留在那里,因此当您进行新调用时,可以节省创建和分配对象的时间,因此您可以获得更快的响应。

这些对象是哪些?- 在上面的几行中说:我没有任何非常清晰的列表,但它们就像代理设置,缓存内存。


再等一会儿,直到有人对此有深入的技术知识并解释了所有东西是如何工作的。

于 2012-06-13T05:20:39.937 回答