我有一个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()
答案 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();
}