在过去的几周里,我们的客户端开始看到数百个这样的“SSLException错误-连接被对等端重置”,我不知道为什么
1.我们正在使用带有okhttp的Retrofit,没有特殊配置
public class OkHttpClientProvider implements IOkHttpClientProvider {
OkHttpClient okHttpClient;
public OkHttpClientProvider() {
this.okHttpClient = createClient();
}
public OkHttpClient getOkHttpClient() {
return this.okHttpClient;
}
private OkHttpClient createClient() {
return new OkHttpClient();
}
}
上面的客户端提供者是一个单例。RestAdapter是使用这个注入的客户端构建的(我们使用dagger)-
RestAdapter.Builder restAdapterBuilder = new RestAdapter.Builder()
.setConverter(converter)
.setEndpoint(networkRequestDetails.getServerUrl())
.setClient(new OkClient(okHttpClientProvider.getOkHttpClient()))
.setErrorHandler(new NetworkSynchronousErrorHandler(eventBus))
);
基于我发现的堆栈溢出解决方案-
1.服务器上的保持活动持续时间为180秒,OkHttp的默认值为300秒
1.服务器返回“连接:close”,但客户端请求发送“Connection:保持活动”
1.服务器支持TLS 1.0 / 1.1 / 1.2并使用Open SSL
1.我们的服务器最近已经转移到另一个托管提供商在另一个地理位置,所以我不知道这些是否是DNS故障或没有
1.我们尝试过调整keepAlive,在服务器上重新配置OpenSSL,但由于某种原因,Android客户端总是收到此错误
1.当你尝试使用应用程序发布内容或进行拉取刷新时,它会立即发生,没有任何延迟(在此异常发生之前,它甚至不会连接到网络或有延迟,这意味着连接已经断开)。但多次尝试以某种方式“修复它”,我们获得了成功。稍后它会再次发生
1.我们已经使服务器上的DNS条目无效,以查看这是否是导致它的原因,但这没有帮助
1.这种情况大多发生在LTE上,但我也在WiFi上看到过
我不想禁用keep alive,因为大多数现代客户端都不这样做。此外,我们使用的是OkHttp 2.4,这是后冰淇淋三明治设备上的一个问题,所以我希望它应该照顾到这些潜在的网络问题。iOS客户端也有这些例外,但接近100倍少(iOS客户端使用AFNetworking 2.0)。我正在努力寻找新的东西来尝试这一点,任何帮助/想法?
更新-通过okhttp添加完整堆栈跟踪
retrofit.RetrofitError: Read error: ssl=0x9dd07200: I/O error during system call, Connection reset by peer
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:390)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy15.getAccessTokenUsingResourceOwnerPasswordCredentials(Unknown Source)
at com.company.droid.repository.network.NetworkRepository.getAccessTokenUsingResourceOwnerPasswordCredentials(NetworkRepository.java:76)
at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.java:88)
at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.java:23)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: javax.net.ssl.SSLException: Read error: ssl=0x9dd07200: I/O error during system call, Connection reset by peer
at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:699)
at okio.Okio$2.read(Okio.java:137)
at okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:306)
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:300)
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:196)
at com.squareup.okhttp.internal.http.HttpConnection.readResponse(HttpConnection.java:191)
at com.squareup.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:80)
at com.squareup.okhttp.internal.http.HttpEngine.readNetworkResponse(HttpEngine.java:917)
at com.squareup.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:793)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:439)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:384)
at com.squareup.okhttp.internal.huc.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:497)
at com.squareup.okhttp.internal.huc.DelegatingHttpsURLConnection.getResponseCode(DelegatingHttpsURLConnection.java:105)
at com.squareup.okhttp.internal.huc.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:25)
at retrofit.client.UrlConnectionClient.readResponse(UrlConnectionClient.java:73)
at retrofit.client.UrlConnectionClient.execute(UrlConnectionClient.java:38)
at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:321)
at retrofit.RestAdapter$RestHandler.invoke(RestAdapter.java:240)
at java.lang.reflect.Proxy.invoke(Proxy.java:397)
at $Proxy15.getAccessTokenUsingResourceOwnerPasswordCredentials(Unknown Source)
at com.company.droid.repository.network.NetworkRepository.getAccessTokenUsingResourceOwnerPasswordCredentials(NetworkRepository.java:76)
at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.java:88)
at com.company.droid.ui.login.LoginTask.doInBackground(LoginTask.java:23)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
]}
8条答案
按热度按时间mrfwxfqh1#
最近我在处理一些遗留代码时遇到了这个问题。在谷歌上搜索后,我发现这个问题无处不在,但没有任何具体的解决方案。我处理了异常消息的各个部分,并在下面进行了分析。
SSLException
:SSL( ssl 层)发生异常,在JDK(openJDK/oracleJDK/AndroidSDK
)的javax.net.ssl
包中实现Read error ssl=# I/O error during system call
:从 ssl 读取时出错。使用本机系统库/驱动程序时出错。请注意,所有平台solaris、Windows等都有自己的套接字库供SSL使用。Windows使用WINSOCK库。Connection reset by peer
:系统库报告了此消息(Solaris报告ECONNRESET
,Windows报告WSAECONNRESET
),表明数据传输中使用的套接字不再可用,因为远程主机强制关闭了现有连接。需要在主机和客户机之间创建新的安全路径了解这个问题,我试图找到连接重置背后的原因,我得出了以下原因:
**Network dropped connection on reset(On Windows(
WSAENETRESET))**
,后续操作失败,并显示**Connection reset by peer(On Windows(
WSAECONNRESET))**
。1.服务器端的事件,如服务突然停止、重新启动、网络接口被禁用,无法通过任何方式进行处理。
1.在服务器端,使用更高的生存时间(TTL)或超时值(如3600秒)为给定端口配置防火墙。
1.客户端可以**"尝试"保持网络活动以避免或减少
Connection reset by peer
。1.正常情况下,持续的网络流量会使连接保持活动状态,并且不会频繁出现问题/异常。
Strong Wifi has least chances of
Connection reset by peer``**。1.对于分组数据传送是间歇性的并且取决于移动网络可用性的移动网络
2G, 3G and 4G
,它可能不重置服务器侧的TTL定时器,并且导致Connection reset by peer
。以下是建议在各种论坛上设置以解决该问题的条件
ConnectionTimeout:
仅在连接超时时使用。如果主机需要时间连接,则此值的较大值会使客户端等待连接。SoTimeout
:套接字超时-表示接收数据包的最长时间,以将连接视为活动。如果在给定时间内未接收到数据,则认为连接已停止/断开。Linger
:当数据排队等待发送并且在套接字上调用关闭套接字函数时,套接字不应关闭的时间。TcpNoDelay
:是否要禁用用于保存和累积TCP数据包并在达到阈值时发送这些数据包的缓冲区?将此设置为true将跳过TCP缓冲,以便立即发送每个请求。网络速度减慢可能是由于数据包传输较小且较频繁而导致网络流量增加所致。因此,上述参数中没有一个有助于保持网络活动,因此是无效的。
我发现一个设置可能有助于解决这个问题,这是这个功能
HttpConnectionParams.setSoKeepAlive(params, true)
SSLException
并检查Connection reset by peer
的异常消息4ngedf3f2#
如果使用
Nginx
遇到类似的问题,那么以下方法可能会有所帮助:在此sslTesturl上扫描您的域,查看您的设备版本是否允许连接。
如果较低版本的设备(如〈Android 4.4.2等)无法连接,由于TLS支持,然后尝试将此添加到您的Nginx配置文件,
jmo0nnb33#
从今天早上开始我们也遇到了同样的问题,现在已经解决了...希望这能有所帮助...
IIS 8上的SSL
1.昨天一切正常,昨晚我们的SSL在IIS站点上更新了。
1.在 checkout 站点绑定到SSL时,注意到IIS 8有一个新的复选框 * Require Server Name Indication *,在启用之前未选中该复选框。
1.这引发了问题。
1.返回IIS,禁用复选框....问题解决!!!
希望这对你有帮助!
llycmphe4#
Android默认支持SSL实现,Android N(API级别24)及以下版本(API级别22)除外
在服务器端实现SSL后,在API级别22以下的设备上进行API调用时,我遇到了这个错误;这是在创建OkHttpClient客户端对象时发生的,并通过添加connectionSpecs()方法OkHttpClient.Builder类进行了修复。
收到的错误是
响应失败:javax.net.ssl.SSLException: SSL握手已中止:SSL = 0xb8882c00:系统调用期间发生I/O错误,对等方重置连接
所以我修正了这个问题,添加了一个检查项
也适用于Android N(API级别24);我在进行HTTP调用时遇到错误,例如
HTTP失败:javax.net.ssl.SSLHandshakeException:握手失败
这一问题通过添加检查(特别是针对Android 7)得以解决,例如
因此,我的最终OkHttpClient对象将类似于:
getSpecsBelowLollipopMR1函数就像,
Tls12SocketFactory类可以在下面的链接中找到(gotev的评论):
要获得更多支持,请在下面添加一些链接,这将对您有详细帮助,
https://developer.android.com/training/articles/security-ssl
D/OK HTTP:〈--HTTP失败:javax.net.ssl.SSLException: SSL握手已中止:ssl = 0x64e3c938:系统调用期间发生I/O错误,对等方重置连接
ltqd579y5#
出现此错误消息的另一个可能原因是HTTP方法被服务器或负载平衡器阻止。
似乎是standard security practice阻止了未使用的HTTP方法。我们遇到了这个问题,因为HEAD被负载平衡器阻止了(但奇怪的是,不是所有的负载平衡服务器,这导致它只在某些时候失败)。我能够测试请求本身是否工作正常,方法是临时将其更改为使用GET方法。
iOS上的错误代码为:请求应用程序代码时出错:错误域=NSURLErrorDomain代码=-1005“网络连接丢失。”
ar7v8xwq6#
我在使用
okhttp/4.0.0-RC1
发送网络请求的Android 5.1.1
设备上遇到此错误。在服务器端设置标头Content-Length: <sizeof response>
解决了此问题。bgibtngc7#
我的问题是与
TIMEZONE
在模拟器genymotion。改变TIMEZONE ANDROID EMULATOR
等于TIMEZONE SERVER
,解决了问题。reference
niknxzdl8#
优雅地处理异常可能非常困难。
问题:每当我向Web服务发出请求时,我都会遇到此javax.net.ssl.SSLException错误,我完全清楚自己已用尽订阅的Internet数据包,但我的移动的应用程序在检查
Connectivity.NetworkAccess == NetworkAccess.Internet
后确认我已连接到Internet。最糟糕的是,javax.net.ssl.SSLException错误会在数据包用尽时使应用程序崩溃。我的案例:在我的案例中,我正在测试如果用户在有互联网连接的情况下尝试登录,但他们正在使用的特定ISP没有可用的数据包订阅,会出现什么问题。嗯,应用程序崩溃并出现javax.net.ssl.SSLException错误,这就是我得到的结果。
**我的解决方案:**我在谷歌上搜索了处理这个问题的最佳方法,但我得到的答案是针对不同的人,所以我决定找出如何实施我的。
首先,作为一般的事情,我用try-catch块包围了我的Web请求代码,如下图所示;
以上代码行的焦点在Catch块中,我将在该块中从API返回登录响应。注意:****code = 0表示Web请求不成功。
在我的ViewModel中,我添加了以下代码行:
我已经附上了我的应用程序在物理Android设备上运行的屏幕截图。Screenshot of the app
**最后的想法:**我仍然相信我自己的错误处理方法在这种情况下甚至可以改进。这是什么好的是,它的跨平台处理。然而,应用程序不会崩溃了,我希望这有助于有人在那里。