Android,HTTP GET没有返回

时间:2011-09-28 03:19:32

标签: android python http

我有一个Android应用程序,通过HTTP向机器人发送命令。 (机器人服务器是使用BaseHttpServer类用Python编写的。)据我所知,我正在应用程序中正确设置我的连接,但大多数请求都无法返回,如果有,则会有很长的延迟。这是初始化代码:

    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);

其中mClient是从Activity共享的变量。

通过使用Log.d消息,我确定前两个请求工作正常,但随后所有后续请求(在单独的AsyncTasks中)挂起,永远不会从执行返回。我还尝试手动创建一个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应用程序。我在主UI中尝试过这种单线程,但也会产生同样的效果。

修改

以下是导致问题的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()

1 个答案:

答案 0 :(得分:0)

这可能与保持活力有关。 Android发送Connection:Keep-Alive,Python发回一个Connection:close。我查看了从Firefox和HttpClient发送的HTTP标头,没有区别(除了Firefox发送一些额外的Accept标头)。不知何故,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();
    }