【问题标题】:Https connection AndroidHttps连接安卓
【发布时间】:2011-06-02 14:53:02
【问题描述】:

我有一个应用程序连接到使用 Entrust 有效证书的 Web 服务。唯一的区别是它是通配符 SSL。

问题是:我得到一个

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

当我使用 3G 时。在 WIFI 上它可以工作,在模拟器上它可以工作,通过我的手机 3G 连接模拟器可以工作。但是我手机上的 3G 应用程序根本不起作用。在 2 个不同网络(Virgin Mobile Canada 和 Fido)上的 HTC Legend CM7.0.3(2.3.3) 和 Nexus S 2.3.3 上进行了测试。

我的设备中有一个 PCAP 转储显示一些错误,但我不太了解它。

确认号:TCP 损坏。 ACK 标志未设置时,确认字段为非零

我也尝试过修复这个question 这个question。我不知道还能去哪里。

顺便说一下,网络服务可以在 3G 上使用浏览器。

我们还使用 HttpRequestInterceptor 的基本身份验证。

我想这就是我能提供的所有细节。如果需要其他内容,请随时询问。

这个question 也有关系,我都试过了,都不管用。

编辑

我开始认为这可能更适合 serverfault.com

这是转储file 和截图

编辑 2

这是我用来连接到相关网络服务的代码。

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

【问题讨论】:

  • 你能添加一些相关的代码,也许会有所帮助。
  • @Nicklas A,添加了一些代码。如果需要特定的东西,请询问。

标签: android https


【解决方案1】:

我们终于找到了问题所在。这与代码无关。

是反向 DNS 超时。因为我没有收到来自反向 DNS 的任何答复,所以我的 apache/ssl 会话提前关闭了。

通过在根设备上使用 Google 的 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));
}

【讨论】:

  • 对nio连接有影响吗?
  • @Kai,不知道,从未测试过。
【解决方案2】:

您尝试过HttpClient on Android : NoHttpResponseException through UMTS/3G中提到的解决方案吗?

复制如下


我终于摆脱了这个问题:只是一个 HTTP 标头,被路上的 squid 服务器处理得很糟糕:

期望:100-继续

默认情况下,Android SDK 上的 DefaultHttpClient 似乎存在。要解决这个问题,只需在您的代码中添加:

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

【讨论】:

  • 我在我的问题中发布了 3 个答案,它们都不起作用,其中之一就是这个。这个解决方案对我不起作用。
  • 哦,我一定打开了其他链接,我的错
【解决方案3】:
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 连接

【讨论】:

  • 这没什么用,因为 httpclient.execute() 上的代码崩溃
  • 看看我的代码,我设置了,反正看看我的回答解决了我的问题。
猜你喜欢
  • 2010-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-13
  • 2012-05-26
  • 2011-05-09
相关资源
最近更新 更多