Android HTTPS 异常 Connection reset by peer

Android HTTPS exception Connection reset by peer(Android HTTPS 异常 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

基础教程推荐