Android HTTPS exception Connection reset by peer(Android HTTPS 异常 Connection reset by peer)
问题描述
我正在开发一个从 Web 服务器下载数据的应用程序.一开始似乎下载数据没有任何问题,但几天前我开始收到这种异常:javax.net.ssl.SSLException:读取错误:ssl=0x7a6588:系统调用期间的 I/O 错误,对等方重置连接
,我不确定导致该问题的原因以及如何解决该问题.这是整个 LogCat
消息:
I'm working on an application which is downloading data from a web server.It seems to download data without any problems in the beginning, but a few days ago I start receiving this kind of exceptions : javax.net.ssl.SSLException: Read error: ssl=0x7a6588: I/O error during system call, Connection reset by peer
and I'm not sure what cause that problem and how can I fix that. Here is the whole LogCat
message :
12-12 11:43:27.950: W/System.err(22010): javax.net.ssl.SSLException: Read error: ssl=0x7a6588: I/O error during system call, Connection reset by peer
12-12 11:43:27.960: W/System.err(22010): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_read(Native Method)
12-12 11:43:27.960: W/System.err(22010): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:788)
12-12 11:43:27.960: W/System.err(22010): at org.apache.harmony.luni.internal.net.www.protocol.http.ChunkedInputStream.read(ChunkedInputStream.java:50)
12-12 11:43:27.960: W/System.err(22010): at java.io.InputStream.read(InputStream.java:157)
12-12 11:43:27.960: W/System.err(22010): at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:225)
12-12 11:43:27.960: W/System.err(22010): at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:178)
12-12 11:43:27.960: W/System.err(22010): at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:174)
12-12 11:43:27.960: W/System.err(22010): at java.io.BufferedInputStream.read(BufferedInputStream.java:319)
12-12 11:43:27.970: W/System.err(22010): at java.io.FilterInputStream.read(FilterInputStream.java:133)
12-12 11:43:27.970: W/System.err(22010): at com.stampii.stampii.synchronization.Synchronization.UseHttpsConnection(Synchronization.java:1367)
12-12 11:43:27.970: W/System.err(22010): at com.stampii.stampii.synchronization.Synchronization$ActivateCollection.doInBackground(Synchronization.java:613)
12-12 11:43:27.970: W/System.err(22010): at com.stampii.stampii.synchronization.Synchronization$ActivateCollection.doInBackground(Synchronization.java:1)
12-12 11:43:27.970: W/System.err(22010): at android.os.AsyncTask$2.call(AsyncTask.java:185)
12-12 11:43:27.970: W/System.err(22010): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
12-12 11:43:27.970: W/System.err(22010): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
12-12 11:43:27.970: W/System.err(22010): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
12-12 11:43:27.970: W/System.err(22010): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
12-12 11:43:27.970: W/System.err(22010): at java.lang.Thread.run(Thread.java:1027)
这就是我的 UseHttpsConnection
方法:
public void UseHttpsConnection(String url, String charset, String query) {
try {
final TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted( final X509Certificate[] chain, final String authType ) {
}
@Override
public void checkServerTrusted( final X509Certificate[] chain, final String authType ) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
} };
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance( "TLS" );
sslContext.init( null, trustAllCerts, new java.security.SecureRandom() );
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
if (url.startsWith("https://")) {
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier(){
public boolean verify(String hostname, SSLSession session) {
return true;
}});
}
System.setProperty("http.keepAlive", "false");
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
connection.setSSLSocketFactory( sslSocketFactory );
connection.setDoOutput(true);
connection.setConnectTimeout(15000 /* milliseconds */ );
connection.setRequestMethod("POST");
connection.setRequestProperty("Charset", charset);
connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=" + charset);
OutputStream output = null;
try {
output = connection.getOutputStream();
output.write(query.getBytes(charset));
} catch (IOException e) {
e.printStackTrace();
showError2("Check your network settings!");
} finally {
if (output != null)
try {
output.close();
} catch (IOException logOrIgnore) {
logOrIgnore.printStackTrace();
}
}
int status = ((HttpsURLConnection) connection).getResponseCode();
Log.d("", "Status : " + status);
for (Entry<String, List<String>> header : connection
.getHeaderFields().entrySet()) {
Log.d("Headers","Headers : " + header.getKey() + "="+ header.getValue());
}
InputStream response = new BufferedInputStream(connection.getInputStream());
int bytesRead = -1;
byte[] buffer = new byte[30 * 1024];
while ((bytesRead = response.read(buffer)) > 0) {
byte[] buffer2 = new byte[bytesRead];
System.arraycopy(buffer, 0, buffer2, 0, bytesRead);
handleDataFromSync(buffer2);
}
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
showError2("Synchronization failed!Please try again.");
} catch (KeyManagementException e) {
e.printStackTrace();
showError2("Error occured.Please try again.");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
showError2("Error occured.Please try again.");
}
}
这是我用来连接和下载数据的 AsyncTask:
And here is my AsyncTask which I'm using to connect and download the data :
public class DeactivateCollection extends AsyncTask <Context, Integer, Void> {
@Override
protected Void doInBackground(Context... arrContext) {
try {
String charset = "UTF-8";
hash = getAuthHash();
SharedPreferences lastUser = PreferenceManager
.getDefaultSharedPreferences(Synchronization.this);
int userId = lastUser.getInt("lastUser", 1);
systemDbHelper = new SystemDatabaseHelper(Synchronization.this, null, 1);
systemDbHelper.initialize(Synchronization.this);
String sql = "SELECT dbTimestamp FROM users WHERE objectId=" + userId;
Cursor cursor = systemDbHelper.executeSQLQuery(sql);
if (cursor.getCount() < 0) {
cursor.close();
} else if (cursor.getCount() > 0) {
cursor.moveToFirst();
timeStamp = cursor.getString(cursor.getColumnIndex("dbTimestamp"));
Log.d("", "timeStamp : " + timeStamp);
}
String query = String.format("debug_data=%s&"
+ "client_auth_hash=%s&" + "timestamp=%s&"
+ "deactivate_collections=%s&" + "client_api_ver=%s&"
+ "set_locale=%s&" + "device_os_type=%s&"
+ "device_sync_type=%s&"
+ "device_identification_string=%s&"
+ "device_identificator=%s&" + "device_resolution=%s",
URLEncoder.encode("1", charset),
URLEncoder.encode(hash, charset),
URLEncoder.encode(timeStamp, charset),
URLEncoder.encode(Integer.toString(deac), charset),
URLEncoder.encode(clientApiVersion, charset),
URLEncoder.encode(locale, charset),
URLEncoder.encode(version, charset),
URLEncoder.encode("14", charset),
URLEncoder.encode(version, charset),
URLEncoder.encode(deviceId, charset),
URLEncoder.encode(resolution, charset));
Log.e("","hash : "+hash);
Log.e("","deactivate : "+Integer.toString(deac));
SharedPreferences useSSLConnection = PreferenceManager.getDefaultSharedPreferences(Synchronization.this);
boolean useSSl = useSSLConnection.getBoolean("UseSSl", true);
if (useSSl) {
UseHttpsConnection(url, charset, query);
} else {
UseHttpConnection(url, charset, query);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... progress) {
Log.d("","ON PROGRESS UPDATE");
}
@Override
protected void onCancelled() {
Log.d("","ON CANCELLED");
}
@Override
protected void onPreExecute()
{
Log.d("","ON PRE EXECUTE");
}
@Override
protected void onPostExecute(Void v) {
Log.d("","ON POST EXECUTE");
}
}
所以任何人都知道如何处理该异常,这样我就可以毫无例外地下载整个数据.或者如果不可能,我该如何解决.
提前致谢!
推荐答案
其实在这种情况下你可以做两种选择.您可以在通过 Internet 下载数据时捕获该异常并创建一个函数,该函数将从它停止的位置再次启动连接.所以你必须想办法在下载数据的同时保存你的进度,因为如果你正在下载大量数据,重新开始这个过程不是一个好主意.
Actually there are two options that you can do in this situation. You can catch that exception while downloading data over internet and create a function which will start the connection again from where it stops. So you have to find a way to save your progress while downloading the data,because if you're downloading big size of data it's not a good idea to start the process again.
您可以做的另一件事是创建一个对话框,该对话框将通知用户同步时出现错误,并让他选择是否要重试操作或取消它.如果用户选择重试选项,我认为是从再次停止的地方重新开始连接将是一个更好的选择.因此,您必须以两种方式保存进度.我认为这对用户更友好.
Another thing that you can do is to create a dialog, which will inform the user that there is error while synchronizing and let him to choose if he want to retry the operation or cancel it.If user select Retry option I think it will be a better option to start the connection again from the where it stops again. So you have to save your progress in both ways. I think that's more user friendly.
这篇关于Android HTTPS 异常 Connection reset by peer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Android HTTPS 异常 Connection reset by peer
基础教程推荐
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01