【问题标题】:HttpsURLConnection and intermittent connectionsHttpsURLConnection 和间歇性连接
【发布时间】:2011-01-11 11:30:43
【问题描述】:

我希望有人可以帮助我解决断断续续的连接问题 使用 HttpsURLConnection 的代码。我正在使用的代码是 下面:

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            conn.setReadTimeout(10 * 1000); 
if conn.getResponseCode() != 200) { 
            Log.v(TAG, "error code:" + conn.getResponseCode()); 
} 

每次我使用它来拉动一个 json 文件。但是,当我再次使用连接发送命令时, 它总是第一次失败。如果我发送它通常会起作用 命令快速(在 5 秒内),但如果我等待一段时间就会失败。 我认为它不是 SSL 问题,因为它是第一次连接 正确,但我在这里可能是错的。我也尝试了很多不同的 变体,例如添加:

conn.setUseCaches(false); 
conn.setRequestProperty("Connection","Keep-Alive"); 
conn.getHostnameVerifier(); 
conn.getSSLSocketFactory(); 
conn.setDoOutput(true); 
conn.setDoInput(true); 
conn.setRequestMethod("POST"); 
conn.wait(100); 

但是,我没有运气。任何帮助将不胜感激。

【问题讨论】:

  • 如果我可以建议使用 LogCat 并将调试语句放在您的代码块中,以便它可以准确地向您报告失败的原因和位置
  • 我从 conn.getResponseCode() 得到的 Logcat 响应是“-1”,我已经搜索过,在 https 连接的 -1 响应代码上找不到任何内容。

标签: android httpurlconnection connection intermittent


【解决方案1】:

先试试System.setProperty("http.keepAlive", "false");

HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

【讨论】:

  • 完美。这行得通。我不知道你可以使用“系统”。我猜在我进行不同的活动之前,SSL 连接一直保持打开状态。谢谢!
  • 是的,我认为这与错误流没有被完全读取有关。
  • code.google.com/p/android/issues/detail?id=2939 应该从 Froyo 开始修复。
  • 在没有证书和握手的情况下传输到我的服务器期间是否安全?
【解决方案2】:

试试这个代码 - 它对我来说非常可靠:

public static final String USER_AGENT = "Mozilla/5.0 (Linux; U; Android 1.1; en-us;dream) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2";
private DefaultHttpClient getThreadSafeHttpClient() {
    final HttpParams params = new BasicHttpParams();
    params.setParameter("http.useragent", USER_AGENT);
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, "UTF-8");
    final SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
    final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
    sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    registry.register(new Scheme("https", sslSocketFactory, 443));
    final ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
    final DefaultHttpClient httpclient = new DefaultHttpClient(manager, params);
    // how to handle retries
    final HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
        public boolean retryRequest(final IOException exception, final int executionCount, final HttpContext context) {
            if (executionCount >= 5) {
                // Do not retry if over max retry count
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                // Retry if the server dropped connection on us
                return true;
            }
            if (exception instanceof SSLHandshakeException) {
                // Do not retry on SSL handshake exception
                return false;
            }
            final HttpRequest request = (HttpRequest) context.getAttribute(ExecutionContext.HTTP_REQUEST);
            final boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
            if (idempotent) {
                // Retry if the request is considered idempotent
                return true;
            }
            return false;
        }

    };
    httpclient.setHttpRequestRetryHandler(myRetryHandler);
    return httpclient;
}

【讨论】:

  • 谢谢...这比我简单的 https url 连接要复杂得多。我不确定如何准确使用它。由于 getThreadSafeHttpClient 函数没有任何输入,我应该在哪里输入我的网址?
  • 你只是用它来获取HttpClient,然后像往常一样使用客户端。类似HttpClient client = getThreadSafeHttpClient();
  • HttpGet get = new HttpGet(url); HttpResponse 响应 = this.client.execute(get);
  • DroidIn,您是否建议始终设置 SSLSocketFactory 和 HostnameVerifier,即使连接在没有它的情况下也能正常工作?
  • 如果您 100% 确定自己不会访问 https,则不必这样做。我只是将此代码作为模板并在初始化 HttpClient 时设置一次
【解决方案3】:

只是对上面 m6tt 的回答的一点补充:

private static void disableConnectionReuseIfNecessary() {
    // HTTP connection reuse which was buggy pre-froyo
    if (!Constants.SUPPORTS_FROYO) {
        System.setProperty("http.keepAlive", "false");
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-20
    • 2018-09-17
    • 2012-10-20
    相关资源
    最近更新 更多