2011-09-28 62 views
1

我有一個Android應用程序通過HTTP向機器人發送命令。 (機器人服務器是使用BaseHttpServer類以Python編寫的。)我儘可能正確地在應用程序中建立連接,但大多數請求無法返回,如果它們執行,則會有很長的延遲。下面是初始化代碼:Android,HTTP GET不返回

private void setupHttpStuff() { 
     HttpParams params = new BasicHttpParams(); 
     ConnManagerParams.setMaxTotalConnections(params, 10); 
     HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1); 

     SchemeRegistry schemeRegistry = new SchemeRegistry(); 
     schemeRegistry.register(
      new Scheme("http", PlainSocketFactory.getSocketFactory(), 1504)); 

     ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry); 
     this.HttpClient = new DefaultHttpClient(cm, params); 
    } 

的GET請求發生在一個的AsyncTask和代碼如下:

HttpContext localContext = new BasicHttpContext(); 
    HttpGet httpGet = new HttpGet(url); 
    mClient.execute(httpGet, localContext); 

在哪裏移動客戶端是從活動共享的變量。

通過使用Log.d消息我已經確定前兩個請求工作正常,但隨後的所有請求(在單獨的AsyncTasks中)掛起並且從不從execute返回。我也嘗試手動創建一個Socket和發送的HttpRequest:

Socket socket = new Socket("192.168.1.45", 1504); 
    HttpParams params = new BasicHttpParams(); 
    DefaultHttpClientConnection conn = new DefaultHttpClientConnection(); 
    conn.bind(socket, params); 
    HttpRequest request = new BasicHttpRequest("GET", "/"); 
    conn.sendRequestHeader(request); 
    HttpResponse response = conn.receiveResponseHeader(); // Hangs here 
    conn.receiveResponseEntity(response); 
    socket.close(); 

但這掛在conn.receiveResponseHeader()線和服務器永遠不會看到該請求。

Python服務器可以很好地處理來自瀏覽器的請求,而不是使用我的Android應用程序。我在主用戶​​界面中也嘗試了這種單線程,但也會產生相同的效果。

編輯

這裏是Python代碼引起的問題:

class MyHand(BaseHTTPServer.BaseHTTPRequestHandler): 

    def do_GET(self): 

     qv = parse_qs(get_qs(urlparse(self.path))) 

     if("method" not in qv): 
      self.send_nack() 

     elif(qv["method"][0] == "drive"): 
      createbot.Drive(int(qv["velocity"][0]), int(qv["radius"][0])) 
      self.send_ack() 

     else: 
      self.send_nack() 

    def send_ack(self, content_type='text/html'): 

     self.send_response(200) 
     self.send_header('Content-type', content_type) 
     self.end_headers() 

    def send_nack(self): 

     self.send_response(500) 
     self.send_header('Content-type', 'text/html') 
     self.end_headers() 
+0

你是一個真正的設備或AVD上測試? – Jack

+0

這是一個真正的設備,Nexus S. – LucasMcGraw

回答

0

以保持活動,這可能是相關的。 Android發送Connection:Keep-Alive並且Python發回Connection:close。我查看了從Firefox和HttpClient發送的HTTP標頭,沒有什麼區別(除了發送一些額外的Accept標頭的Firefox)。不知何故,Android希望Python服務器發送除HTTP/1.1 200 OK\nContent-type: text/html以外的東西,因此保持套接字打開。我最終編寫了自己的基本HTTP服務器和客戶端。

Python代碼:

class SingleTCPHandler(SocketServer.BaseRequestHandler): 

    def handle(self): 
     data = self.request.recv(1024) 
     parts = data.rsplit(" ") 
     if (parts[0] != "GET"): 
      self.request.close() 
      return 

     url = parts[1].split("?")[1] 
     qv = parse_qs(url) 
     ... 

安卓

Socket socket = null; 
    PrintWriter output = null; 

    try { 
     socket = new Socket(this.ipAddress, this.portNo); 
     output = new PrintWriter(new BufferedWriter 
       (new OutputStreamWriter(socket.getOutputStream())), true); 
     output.println("GET " + url); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } finally { 
     try { 
      if (socket != null) 
       socket.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     if (output != null) 
      output.close(); 
    }