第一次HTTP POST和GET尝试总是很慢 - 这个操作系统是相关的还是网络?

Tam*_*Tam 6 networking android http http-get http-post

我现在刚刚开始在HTTP中弄湿我的脚.我一直使用GET和POST计算简单的HTTP请求.我使用的网页是3行php检查正确的$ _GET []和$ _POST []然后只是回显字符"1".我使用POST和GET使用相同的单个短名称/值对,希望不需要数据包碎片来解决问题,所有这些都是在一个脱离UI线程的线程上完成的.在计时时,请求会在手机上多次循环.一切顺利.(见下面的代码)也就是说,我回复了"1"的回答.但是存在一个持续的时间问题.我观察到的是:

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

  2. 其余的尝试对两者来说都要快得多.

  3. GET总是比POST快.

所有这些都适用于3G和Wifi连接(但是Wifi的整体速度比预期的要快得多).

我已经尝试使用BasicResponseHandler(),并使用更多手动缓冲IO流方法,结果相同.

我相信我理解3.因为POST需要两个传输,一个用于'HTTP 100'然后返回数据包主体.- 它是否正确?

我的主要问题是第一次请求尝试中发生的事情是如此之慢?有时需要几秒钟(!).是网络是什么东西或Android将它放入创建某种队列的套接字?如果是Android,有没有办法更正确地编码并避免这种情况?是否有关于保持套接字打开以使其在执行期间只出现一次的问题?如果是这样,这样做是好的做法吗?不可否认,这个问题我最无能为力.

我已经找到了一些关于此的讨论,但没有一个直接达到这个方面.

-

GET和POST方法的基本代码如下所示(减去try/catches),并在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
Run Code Online (Sandbox Code Playgroud)

和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
Run Code Online (Sandbox Code Playgroud)

这些被称为:

Runnable HTTPGETJob = new HTTPGETTask(NS);
Thread HTTPGETThread = new Thread(HTTPGETJob, "HTTPGETThread");
HTTPGETThread.setPriority(Thread.MAX_PRIORITY);
HTTPGETThread.start();
Run Code Online (Sandbox Code Playgroud)

和:

Runnable HTTPPOSTJob = new HTTPPOSTTask(NS);
Thread HTTPPOSTThread = new Thread(HTTPPOSTJob, "HTTPPOSTThread");
HTTPPOSTThread.setPriority(Thread.MAX_PRIORITY);
HTTPPOSTThread.start();
Run Code Online (Sandbox Code Playgroud)

使用runnables:

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);
 }
};
Run Code Online (Sandbox Code Playgroud)

和,

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);
 }
};  
Run Code Online (Sandbox Code Playgroud)

输出通常是:

(0)GET-Round Trip是368 ms.

(1)GET-Round Trip是103毫秒.

(2)GET-Round Trip是98毫秒.

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

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


(0)回合旅行是1289毫秒.

(1)回合后旅行是567毫秒.

(2)回合后旅行是589毫秒.

(3)回合后旅行是496毫秒.

(4)回合后旅行是557毫秒.

Lal*_*ani 1

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

httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, 
                                                        HttpVersion.HTTP_1_1);
Run Code Online (Sandbox Code Playgroud)