2011-12-12 16 views
5

Pracuję nad aplikacją, która pobiera dane z serwera WWW. Wydaje się, że na początku pobierane są dane bez żadnych problemów, ale kilka dni temu zaczynam otrzymywać tego rodzaju wyjątki : javax.net.ssl.SSLException: Read error: ssl=0x7a6588: I/O error during system call, Connection reset by peer i nie jestem pewien, co przyczyną tego problemu i jak mogę to naprawić. Oto cała LogCat wiadomość:Wyjątek Android HTTPS Wyzerowanie połączenia przez równorzędnego użytkownika

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) 

to co mam na moim UseHttpsConnection metody:

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."); 
    } 
} 

I tu jest moje AsyncTask które używam, aby połączyć i pobrać dane:

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"); 

    } 
    } 

Każdy ma pomysł, jak sobie poradzić z tym wyjątkiem, aby móc pobierać całe dane bez żadnych wyjątków. Albo jak mogę to naprawić, jeśli to niemożliwe.

Z góry dziękuję!

Odpowiedz

6

W rzeczywistości istnieją dwie opcje, które można wykonać w tej sytuacji. Możesz przechwycić ten wyjątek podczas pobierania danych przez Internet i utworzyć funkcję, która uruchomi połączenie ponownie od miejsca, w którym się zatrzymuje. Musisz więc znaleźć sposób na zapisanie swoich postępów podczas pobierania danych, ponieważ jeśli pobierasz duże ilości danych, nie jest dobrym pomysłem ponowne rozpoczęcie procesu.

Inną rzeczą, którą możesz zrobić, jest utworzenie okna dialogowego, które poinformuje użytkownika o błędzie podczas synchronizacji i pozwoli mu wybrać, czy chce ponownie wykonać operację, czy ją anulować. Jeśli użytkownik wybierze opcję Ponów, myślę, że będzie to lepsza opcja, aby ponownie nawiązać połączenie z miejsca, w którym ponownie się zatrzymuje. Musisz więc zapisać swoje postępy w obie strony. Myślę, że jest bardziej przyjazny dla użytkownika.

Powiązane problemy