2011-06-02 93 views
4

我有一個應用程序連接到使用Entrust有效證書的Web服務。唯一的區別是它是通配符SSL。https連接Android

的問題是:我得到一個

ERROR/NoHttpResponseException(5195): org.apache.http.NoHttpResponseException: The target server failed to respond 

當我在3G上。當在WIFI上它工作,在模擬器上工作,通過我的手機3G工作模擬器。但是3G手機上的應用根本無法工作。在兩個不同的網絡(Virgin Mobile Canada和Fido)上測試HTC Legend CM7.0.3(2.3.3)和Nexus S 2.3.3。

我有一個PCAP轉儲從我的設備顯示一些錯誤,但我不明白它真的很好。

確認號碼:斷開的TCP。確認字段爲非零而ACK標誌未設置

我也嘗試了此questionquestion的修復。我不知道要去哪裏。

順便說一句,網絡服務與3G上的瀏覽器一起工作。

我們也使用基本身份驗證與HttpRequestInterceptor。

我想這是我能給的所有細節。如果需要其他東西,請隨時詢問。

這個question也有關係,我已經嘗試了兩個修復,都沒有工作。

編輯

我開始認爲這可能是更適合serverfault.com

這是轉儲file和截圖

PCAP

編輯2

這是我用來連接到有問題的Web服務的代碼。

protected HttpEntity sendData(List<NameValuePair> pairs, String method) 
      throws ClientProtocolException, IOException, 
      AuthenticationException { 

     pairs.add(new BasicNameValuePair(KEY_SECURITY, KEY)); 
     pairs.add(new BasicNameValuePair(LANG_KEY, lang)); 
     pairs.add(new BasicNameValuePair(OS_KEY, OS)); 
     pairs.add(new BasicNameValuePair(MODEL_KEY, model)); 
     pairs.add(new BasicNameValuePair(CARRIER_KEY, carrier)); 

     DefaultHttpClient client = getClient(); 

     HttpPost post = new HttpPost(); 
     try { 
      post.setHeader("Content-Type", "application/x-www-form-urlencoded"); 
      post.setEntity(new UrlEncodedFormEntity(pairs)); 
     } catch (UnsupportedEncodingException e1) { 
      Log.e("UnsupportedEncodingException", e1.toString()); 
     } 

     URI uri = URI.create(method); 

     post.setURI(uri); 

     client.addRequestInterceptor(preemptiveAuth, 0); 

     HttpHost target = new HttpHost(host, port, protocol); 
     HttpContext httpContext = new BasicHttpContext(); 

     HttpResponse response = client.execute(target, post, httpContext); 
     int statusCode = response.getStatusLine().getStatusCode(); 

     if (statusCode == 401) { 
      throw new AuthenticationException("Invalid username or password"); 
     } 

     return response.getEntity(); 
    } 
+0

您可以添加一些相關的代碼,也許可以幫助。 – 2011-06-09 20:26:21

+0

@Nicklas A,添加了一些代碼。如果需要某些具體的東西,請問。 – 2011-06-09 20:43:40

回答

2

我們終於發現了問題。這不是代碼相關的。

這是反向DNS超時。因爲我沒有收到來自反向DNS的任何答案,所以我的apache/ssl會話被提前關閉。

通過使用谷歌的DNS在一個有根的設備上工作。

現在要做的唯一事情就是修復我們的反向DNS。

這裏是一個解決辦法:http://code.google.com/p/android/issues/detail?id=13117#c14

請撥打DefaultHttpClient或AndroidHttpClient實例此方法。它將阻止反向DNS查找。

private void workAroundReverseDnsBugInHoneycombAndEarlier(HttpClient client) { 
    // Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice Cream Sandwich) 
    // http://code.google.com/p/android/issues/detail?id=13117 
    SocketFactory socketFactory = new LayeredSocketFactory() { 
     SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory(); 
     @Override public Socket createSocket() throws IOException { 
      return delegate.createSocket(); 
     } 
     @Override public Socket connectSocket(Socket sock, String host, int port, 
       InetAddress localAddress, int localPort, HttpParams params) throws IOException { 
      return delegate.connectSocket(sock, host, port, localAddress, localPort, params); 
     } 
     @Override public boolean isSecure(Socket sock) throws IllegalArgumentException { 
      return delegate.isSecure(sock); 
     } 
     @Override public Socket createSocket(Socket socket, String host, int port, 
       boolean autoClose) throws IOException { 
      injectHostname(socket, host); 
      return delegate.createSocket(socket, host, port, autoClose); 
     } 
     private void injectHostname(Socket socket, String host) { 
      try { 
       Field field = InetAddress.class.getDeclaredField("hostName"); 
       field.setAccessible(true); 
       field.set(socket.getInetAddress(), host); 
      } catch (Exception ignored) { 
      } 
     } 
    }; 
    client.getConnectionManager().getSchemeRegistry() 
      .register(new Scheme("https", socketFactory, 443)); 
} 
+0

它影響nio連接? – Kai 2012-01-27 20:48:14

+0

@凱,不知道,從來沒有測試過。 – 2012-01-27 23:54:06

1

您是否嘗試過在HttpClient on Android : NoHttpResponseException through UMTS/3G中提到的解決方案?

複製下面


我終於擺脫了這個問題:一個簡單的HTTP標頭竟被通過道路上的魷魚服務器處理:

期望:100繼續

在android SDK上,它似乎默認使用DefaultHttpClient。爲了解決這個問題,只需在您的代碼:

HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false); 
+0

我在我的問題中發佈了3個答案,他們都不工作,其中一個就是這個。此解決方案不適合我。 – 2011-06-09 20:17:40

+0

哦,我必須打開一些其他的鏈接,我的壞 – 2011-06-09 20:26:57

-1
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); 

nameValuePairs.add(new BasicNameValuePair("year","1980")); 

//http post 

try{ 

     HttpClient httpclient = new DefaultHttpClient(); 

     HttpPost httppost = new HttpPost("http://example.com/getAllPeopleBornAfter.php"); 

     httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 

     HttpResponse response = httpclient.execute(httppost); 
     HttpEntity entity = response.getEntity(); 

InputStream is = entity.getContent(); 

}catch(Exception e){ 

     Log.e("log_tag", "Error in http connection "+e.toString()); 

} 

//convert response to string 

try{ 

BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8); 

     StringBuilder sb = new StringBuilder(); 

String line = null; 

while ((line = reader.readLine()) != null) { 

       sb.append(line + "n"); 

} 

     is.close(); 

     result=sb.toString(); 

}catch(Exception e){ 

     Log.e("log_tag", "Error converting result "+e.toString()); 

} 

參考此代碼爲HTTP連接

+0

這是相當無用的,因爲代碼崩潰httpclient.execute() – 2011-06-10 12:55:56

+0

becoz在HttpPost設置它自己的網址比工作正常 – himanshu 2011-09-19 11:38:45

+0

看看我的代碼,我設置它無論如何,看看我的答案,解決了我的問題。 – 2011-09-19 16:36:47