2011-12-12 4 views
5

웹 서버에서 데이터를 다운로드하는 응용 프로그램에서 작업하고 있습니다. 처음에는 문제없이 데이터를 다운로드 할 수 있지만 며칠 전부터 이런 종류의 예외를 받기 시작합니다. : javax.net.ssl.SSLException: Read error: ssl=0x7a6588: I/O error during system call, Connection reset by peer 그리고 그 문제의 원인은 무엇이고 어떻게 해결할 수 있는지 잘 모르겠습니다.Android HTTPS 예외 피어에 의한 연결 재설정

:

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를 수 있습니다 :

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 방법에있어 무엇입니까 다음은 전체 LogCat 메시지는

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

    } 
    } 

누구나 예외를 처리하는 방법을 알고 있으므로 예외없이 전체 데이터를 다운로드 할 수 있습니다. 또는 불가능할 경우 어떻게 해결할 수 있습니까?

미리 감사드립니다.

답변

6

실제로이 상황에서 수행 할 수있는 두 가지 옵션이 있습니다. 인터넷을 통해 데이터를 다운로드하는 동안 예외를 잡을 수 있으며 중지 된 위치에서 다시 연결을 시작하는 기능을 만들 수 있습니다. 따라서 데이터를 다운로드하는 동안 진행 상황을 저장하는 방법을 찾아야합니다. 큰 크기의 데이터를 다운로드하는 경우 프로세스를 다시 시작하는 것이 좋지 않기 때문입니다.

당신이 할 수있는 또 다른 일은 동기화하는 동안 오류가 있음을 사용자에게 알리고 그가 작업을 다시 시도하거나 취소 할지를 선택하게하는 대화 상자를 만드는 것입니다. 사용자가 재 시도 옵션을 선택하면 다시 멈추는 위치에서 다시 연결을 시작하는 것이 더 좋은 옵션이 될 것입니다. 따라서 두 가지 방법으로 진행 상황을 저장해야합니다. 나는 그것이 더 사용자 친화적 인 것 같아요.

관련 문제