Java 从Android应用程序与服务器通信时出现各种HTTPs错误
更新:2015年1月4日 我仍然有这些问题。我们应用程序的用户增加了,我看到了 所有类型的网络错误。我们的应用程序每次都会发送电子邮件 是应用程序上的网络相关错误 我们的应用程序不支持金融交易,因此重新提交不是真的 幂等-非常害怕启用HttpClient的重试功能。 我们在服务器上做了一些响应缓存来处理 重新提交由用户显式完成。然而,仍然没有解决办法 在没有不良用户体验的情况下工作 原始问题 我有一个android应用程序,作为用户操作的一部分发布数据。数据中包含少量图像&我将它们打包为Protobuf消息(实际上是字节数组),并通过HTTPS连接将其发布到服务器 虽然该应用程序在大部分情况下运行良好,但我们偶尔会看到连接错误。现在,我们有一些用户处于相对较慢的网络区域(2G连接),这一问题变得更加突出。然而,这个问题并不局限于连接速度慢的地区,而是存在于使用WiFi和3G连接的客户身上 以下是我们在应用程序日志中注意到的少数例外情况 下面一个发生在5分钟后,因为我已经将套接字超时设置为5分钟。在本例中,应用程序试图发布145kb的数据 堆栈跟踪java.net.SocketTimeoutException:读取超时 位于org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_read(本机 (方法) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:662) 位于org.apache.http.impl.io.AbstractSessionInputBuffer.fillBuffer(AbstractSessionInputBuffer.java:103) 位于org.apache.http.impl.io.AbstractSessionInputBuffer.readLine(AbstractSessionInputBuffer.java:191) 低于1发生2.5分钟(套接字超时设置为5分钟),客户端发送144kb的数据 javax.net.ssl.SSLException:写入错误:ssl=0x5e4f4640:I/O错误 在系统调用期间,管道断开 请访问org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_write(Native (方法) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:704) 位于org.apache.http.impl.io.AbstractSessionOutputBuffer.write(AbstractSessionOutputBuffer.java:109) 位于org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113) 1分钟后发生了低于1的情况 堆栈跟踪javax.net.ssl.SSLException:对等方关闭的连接 位于org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(本机 (方法) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:378) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream(OpenSSLSocketImpl.java:634) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:605) 77秒后发生了低于1的情况 堆栈跟踪javax.net.ssl.SSLException:ssl握手中止: ssl=0x5e2baf00:系统调用期间发生I/O错误,对等方重置连接 位于org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(本机 (方法) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:378) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream(OpenSSLSocketImpl.java:634) 位于org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getInputStream(OpenSSLSocketImpl.java:605) 位于org.apache.http.impl.io.SocketInputBuffer。(SocketInputBuffer.java:70) 15秒后发生以下情况(连接超时设置为15秒) 所用时间:15081堆栈跟踪 org.apache.http.conn.ConnectTimeoutException:连接到 /103.xx.xx.xx:443超时 位于org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:121) 位于org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:144) 位于org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164) 位于org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119) 位于org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:365) 下面是我用来发布Request的源代码片段Java 从Android应用程序与服务器通信时出现各种HTTPs错误,java,android,apache,ssl,nginx,Java,Android,Apache,Ssl,Nginx,更新:2015年1月4日 我仍然有这些问题。我们应用程序的用户增加了,我看到了 所有类型的网络错误。我们的应用程序每次都会发送电子邮件 是应用程序上的网络相关错误 我们的应用程序不支持金融交易,因此重新提交不是真的 幂等-非常害怕启用HttpClient的重试功能。 我们在服务器上做了一些响应缓存来处理 重新提交由用户显式完成。然而,仍然没有解决办法 在没有不良用户体验的情况下工作 原始问题 我有一个android应用程序,作为用户操作的一部分发布数据。数据中包含少量图像&我将它们打包为Prot
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 15000); //15 seconds
HttpConnectionParams.setSoTimeout(params, 300000); // 5 minutes
HttpClient client = getHttpClient(params);
HttpPost post = new HttpPost(uri);
post.setEntity(new ByteArrayEntity(requestByteArray));
HttpResponse httpResponse = client.execute(post);
....
public static HttpClient getHttpClient(HttpParams params) {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new TrustAllCertsSSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.STRICT_HOSTNAME_VERIFIER);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
DefaultHttpClient client = new DefaultHttpClient(ccm, params);
// below line of code will disable the retrying of HTTP request when connection is timed
// out.
client.setHttpRequestRetryHandler(new DefaultHttpRequestRetryHandler(0, false));
return client;
} catch (Exception e) {
return new DefaultHttpClient();
}
}
我读过一些论坛,指出我们应该使用HttpUrlConnection类。我确实做了代码更改以用作热修复程序。虽然它可以在我的三星手机上运行,但它似乎在用户使用的手机中存在一些问题,甚至无法连接到我们的网站。我不得不将它回滚,但如果根本原因可以锁定到DefaultHttpClient,我可以重新查看它
我们的web服务器是nginx,我们的web服务运行在ApacheTomcat上。
客户大多使用安卓4.1+手机。我从其手机中检索到上述堆栈跟踪信息的客户正在使用Micromax A110Q手机和Android 4.2.1
对此的任何意见都将不胜感激。非常感谢
更新:
org.apache.http.conn.ConnectTimeoutException:连接到/103.xx.xx.x
if (client != null) { client.getConnectionManager().shutdown();
}
client_max_body_size 5M;
proxy_read_timeout 300;