Android HttpPost 与 Python CGI 服务器不兼容
我正在开发一个安卓应用,需要把数据提交到我的Python CGI服务器。通常我用HttpGet从服务器获取数据,这些请求都能正常快速地工作。但是当我尝试用HttpPost推送数据时,程序就会一直卡住,直到我长按模拟器的返回键强制退出程序。CGI服务器似乎开始执行脚本,但在我强制退出安卓应用之前,它一直没有返回。当CGI脚本返回时,它显示CGI script exited OK
,但实际上什么都没做。
目前我是在UI线程中执行请求。我知道应该使用AsyncTask来处理这个问题,但我想在找到好的解决方案之前先找到一个临时的解决办法。
我花了三天时间尝试不同的方法,并查看论坛,但都没有找到解决方案。我非常希望能得到一些建议。以下是我安卓代码的相关部分:
private final String serverIP = "10.0.2.2";
HttpClient httpclient = new DefaultHttpClient();
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 5000);
String URI = "http://"+serverIP+":8000/cgi-bin/test.py?order_submit=0";
HttpPost post = new HttpPost(URI);
List<NameValuePair> kvPairs = new ArrayList<NameValuePair>(2);
kvPairs.add(new BasicNameValuePair("name", "bob"));
kvPairs.add(new BasicNameValuePair("surname", "the builder"));
try {
Log.i(TAG, "Trying to set Entity");
post.setEntity(new UrlEncodedFormEntity(kvPairs, HTTP.UTF_8));
Log.i(TAG, "Trying to Post");
HttpResponse response = httpclient.execute(post);
Log.i(TAG, "execute done");
httpclient.getConnectionManager().closeExpiredConnections();
} catch (ClientProtocolException e) {
Log.e(TAG,e.toString());
} catch (UnsupportedEncodingException e) {
Log.e(TAG,e.toString());
} catch (IOException e) {
Log.e(TAG,e.toString());
}
在LogCat中输出了以下内容:
INFO/App:(534): Trying to set Entity
INFO/App:(534): Trying to Post
ERROR/App:(534): java.net.SocketTimeoutException: The operation timed out
我的Python CGI服务器脚本如下:
import os, sys, cgi, csv
import cgitb #CGI error backtracer
cgitb.enable()
form = cgi.FieldStorage()
if "order_submit" in form:
ofile = open(os.getcwd() + "/Forms/Output/foo.csv", "wb")
writer = csv.writer(ofile, delimiter=',', quotechar='"',quoting=csv.QUOTE_ALL)
writer.writerow(["Name", form["name"].value])
writer.writerow(["Surname", form["surname"].value])
ofile.close()
在安卓应用请求超时后,foo.csv文件仍然不存在。即使脚本的if部分包含以下内容,并且根本不使用CGI表单,情况也是一样:
if "order_submit" in form:
ofile = open(os.getcwd() + "/Forms/Output/foo.csv", "wb")
writer = csv.writer(ofile, delimiter=',', quotechar='"',quoting=csv.QUOTE_ALL)
writer.writerow(["Name", "harry"])
ofile.close()
在httpclient.execute(post);
之后,事件的顺序是这样的:
应用程序: httpclient.execute(post);
CGI服务器: POST /cgi-bin/test.py?order_submit=0 HTTP/1.1" 200
CGI服务器: 开始执行第二个Python脚本
等待了几秒钟...
应用程序: java.net.SocketTimeoutException: The operation timed out
Python脚本: 创建了正确的虚拟文件
CGI服务器: CGI script exited OK
2 个回答
这个错误的意思是,给定的IP地址无法访问,或者是8000端口被你的网络服务提供商(ISP)屏蔽了,或者是被防火墙挡住了。
我把
HttpClient httpclient = new DefaultHttpClient();
HttpParams params = httpclient.getParams();
HttpConnectionParams.setConnectionTimeout(params, 5000);
HttpConnectionParams.setSoTimeout(params, 5000);
改成了
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, timeout);
HttpConnectionParams.setSoTimeout(params, timeout);
HttpClient httpclient = new DefaultHttpClient(params);
现在一切都正常了。我觉得我没有改其他的东西。BasicHttpParams
一定是初始化了一些东西,而 DefaultHttpClient
没有,这很奇怪,因为我之前用的方式在 HttpGet
上也没问题。