Android HttpPost не работает с CGI-сервером Python - PullRequest
1 голос
/ 08 марта 2011

Я создаю приложение для Android, и мне нужно отправить данные на мой CGI-сервер python.Я обычно вытаскиваю данные с сервера с помощью HttpGet, и все эти звонки работают правильно и быстро.Когда я пытаюсь отправить данные с помощью HttpPost, программа зависает на неопределенное время, пока я долго не нажму кнопку возврата на эмуляторе и принудительно выйду из программы.Сервер CGI, похоже, запускает скрипт, но не возвращается, пока я не принудительно выйду из приложения Android.Когда скрипт CGI возвращается, он говорит CGI script exited OK, но ничего не сделал.

В данный момент я выполняю запрос в потоке пользовательского интерфейса.Я знаю, что это должно быть сделано в AsyncTask, но я хочу найти решение, прежде чем попробовать хорошее решение.

Я провел 3 дня, пробуя разные вещи и безуспешно просматривая форумы.Я действительно ценю предложения.Вот соответствующая часть моего кода Android:

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

После истечения времени ожидания запроса приложения Android файл 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-сервер: запускает 2-й скрипт Python
несколько секунд ожидания ...
Приложение: java.net.SocketTimeoutException: The operation timed out
Python Script: создает правильный фиктивный файл
CGI-сервер: CGI script exited OK

Ответы [ 2 ]

0 голосов
/ 09 марта 2011

Я изменил

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.

0 голосов
/ 08 марта 2011

Ошибка звучит так, как будто данный IP-адрес недоступен или порт 8000 заблокирован провайдером или защищен брандмауэром.

...