2011-11-08 39 views
9

我讓我的應用程序和somtimes POST請求(如果我有一個巨大的後的數據量),出現下列錯誤:SSL破裂的管道

avax.net.ssl.SSLException: Write error: ssl=0x2f0610: I/O error during system call, Broken pipe

而在代碼執行http.execute(httpost)下面。 有誰知道如何避免這種情況?

我嘗試使用AndroidHttpClient,但無法找到有效的基本身份驗證方式 而我嘗試了一個HttpsUrlConnection,但得到相同的錯誤。

public static String makePOSTRequest(String s, List<NameValuePair> nvps, 
     String encoding) { 
     String ret = ""; 
     UsernamePasswordCredentials c = new UsernamePasswordCredentials("XXX", "YYY"); 
     BasicCredentialsProvider cP = new BasicCredentialsProvider(); 
     cP.setCredentials(AuthScope.ANY, c); 

     HttpParams httpParams = new BasicHttpParams(); 
     int connection_Timeout = 5000; 
     HttpConnectionParams.setConnectionTimeout(httpParams, 
       connection_Timeout); 
     HttpConnectionParams.setSoTimeout(httpParams, connection_Timeout); 
     DefaultHttpClient http = new DefaultHttpClient(httpParams); 
     http.setCredentialsProvider(cP); 
     HttpResponse res; 
     try { 
      HttpPost httpost = new HttpPost(s); 
      httpost.setEntity(new UrlEncodedFormEntity(nvps, 
        HTTP.DEFAULT_CONTENT_CHARSET)); 
      res = http.execute(httpost); 
      InputStream is = res.getEntity().getContent(); 
      BufferedInputStream bis = new BufferedInputStream(is); 
      ByteArrayBuffer baf = new ByteArrayBuffer(50); 
      int current = 0; 
      while ((current = bis.read()) != -1) { 
       baf.append((byte) current); 
      } 
      res = null; 
      httpost = null; 
      ret = new String(baf.toByteArray(), encoding); 
      break; 
     } catch (ClientProtocolException e) { 
      ret = e.getMessage(); 

     } catch (IOException e) { 
      ret = e.getMessage(); 
     } 
    return ret; 
} 

編輯: 下面的代碼是用於上傳文件,如果我嘗試上傳小文件,代碼工作,但如果文件越來越大,我收到破裂的管道錯誤。使用更快的Internet連接會增加文件大小,這似乎是服務器重置連接之前的時間問題。

public static boolean upload_image2(String url, 
     List<NameValuePair> nameValuePairs, File file, String encoding) { 
    boolean erg = false; 

        HttpParams httpParams = new BasicHttpParams(); 
      int connection_Timeout = 120000; 

    HttpConnectionParams.setConnectionTimeout(httpParams,connection_Timeout); 
     HttpConnectionParams.setSoTimeout(httpParams, connection_Timeout); 
     http = new DefaultHttpClient(httpParams); 
     HttpResponse res; 
     UsernamePasswordCredentials c = new UsernamePasswordCredentials(username, password); 
     BasicCredentialsProvider cP = new BasicCredentialsProvider(); 
     cP.setCredentials(AuthScope.ANY, c); 


     try { 
      HttpPost httpost = new HttpPost(url); 

      MultipartEntity entity = new MultipartEntity(
        HttpMultipartMode.STRICT); 

      FileBody isb = new FileBody(file, "application/*"); 
      entity.addPart("File", isb); 
      for (int index = 0; index < nameValuePairs.size(); index++) { 
       ContentBody cb; 
       // Normal string data 
       cb = new StringBody(nameValuePairs.get(index).getValue(), 
         "", null); 
       entity.addPart(nameValuePairs.get(index).getName(), cb); 
      } 

      httpost.setEntity(entity); 

      res = http.execute(httpost); 
      InputStream is = res.getEntity().getContent(); 
      BufferedInputStream bis = new BufferedInputStream(is); 
      ByteArrayBuffer baf = new ByteArrayBuffer(50); 
      int current = 0; 
      while ((current = bis.read()) != -1) { 
       baf.append((byte) current); 
      } 
      res = null; 
      httpost = null; 
      String ret = new String(baf.toByteArray(), encoding); 
      LastError = ret; 
      erg = true; 
     } catch (ClientProtocolException e) { 
      // TODO Auto-generated catch block 
      LastError = e.getMessage(); 
      erg = false; 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      LastError = e.getMessage(); 
      erg = false; 
     } 
    return erg; 
} 
+0

請參閱http://stackoverflow.com/questions/2899079/custom-ssl-handling-stopped-working-on-android-2-2-froyo/2906293#comment7925084_2906293 – tonys

+0

thx,但已經嘗試,同樣的錯誤。我使用代理的請求,但在我的WM應用程序它運行沒有錯誤,必須依賴於Android系統 – 2red13

回答

1

我是不是能夠解決與DefaultHttpClient,AndroidHttpClient或抽象的問題,但最後發現通過頭部而不是CredentielsService與HttpsUrlRequest螞蟻認證的解決方案:

public static boolean upload_image5(String urls,File file, String encoding){ 
    HttpURLConnection connection = null; 
    DataOutputStream outputStream = null; 
    DataInputStream inputStream = null; 
    String myfilename = file.getName(); 
    String urlServer = urls; 
    String lineEnd = "\r\n"; 
    String twoHyphens = "--"; 
    String boundary = "*****"; 
    boolean erg = false; 
    int bytesRead, bytesAvailable, bufferSize; 
    byte[] buffer; 
    int maxBufferSize = 1*1024*1024; 

    try 
    { 
    FileInputStream fileInputStream = new FileInputStream(file); 

    URL url = new URL(urlServer); 
    connection = (HttpsURLConnection) url.openConnection(); 

    // Allow Inputs & Outputs 
    connection.setDoInput(true); 
    connection.setDoOutput(true); 
    connection.setUseCaches(false); 

    // Enable POST method 
    connection.setRequestMethod("POST"); 

    connection.setRequestProperty("Connection", "Keep-Alive"); 
    connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary); 
    connection.addRequestProperty("Authorization","Basic [YOUR MD5 LOGIN VALUE]"); 
    outputStream = new DataOutputStream(connection.getOutputStream()); 
    outputStream.writeBytes(twoHyphens + boundary + lineEnd); 

    outputStream.writeBytes("Content-Disposition: form-data; name=\"DestFileName\""); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(myfilename); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(twoHyphens + boundary + lineEnd); 
    outputStream.writeBytes("Content-Disposition: form-data; name=\"Target\""); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes("DOC"); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(twoHyphens + boundary + lineEnd); 
    outputStream.writeBytes("Content-Disposition: form-data; name=\"filename\""); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(myfilename); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(twoHyphens + boundary + lineEnd); 
    outputStream.writeBytes("Content-Disposition: form-data; name=\"File\"; filename=\"" + myfilename + "\""); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes("Content-Type: application/*"); 
    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(lineEnd); 
    //hier File schreiben 
    bytesAvailable = fileInputStream.available(); 
    bufferSize = Math.min(bytesAvailable, maxBufferSize); 
    buffer = new byte[bufferSize]; 
    bytesRead = fileInputStream.read(buffer, 0, bufferSize); 

    while (bytesRead > 0) 
    { 
    outputStream.write(buffer, 0, bufferSize); 
    bytesAvailable = fileInputStream.available(); 
    bufferSize = Math.min(bytesAvailable, maxBufferSize); 
    bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
    } 

    outputStream.writeBytes(lineEnd); 
    outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 


    fileInputStream.close(); 


    try { 
     inputStream = new DataInputStream(connection.getInputStream()); 
     StringBuilder response = new StringBuilder(); 
     String line; 
     while ((line = inputStream.readLine()) != null) { 
      response.append(line).append('\n'); 
     } 
     LastError =response.toString(); 
     erg = true; 
    } catch (IOException e) { 
     LastError = e.getMessage(); 
     erg = false; 
    } finally { 
     if (inputStream != null){ 
      try { 
       inputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    outputStream.flush(); 
    outputStream.close(); 
    } 
    catch (Exception ex) 
    { 
     LastError = ex.getMessage(); 
     erg = false; 
    } 
    return erg; 
} 
1

我已經得到了同樣的錯誤。問題是在Android的圖書​​館,是使用DefaultHttpClient由於Android API等級1已經出現,並由於Android API 8級。AndroidHttpClient已可這是在錯誤的Android https://code.google.com/p/android/issues/detail?id=8625

我的問題是: 默認超時是60秒。當我在Wireshark中運行連接時。這是創建握手,他一直在等待ApplicationData,但他沒有得到它,所以超時後發送FIN和我得到:javax.net.ssl.SSLException:寫入錯誤:ssl = 0x2f0610:I/O錯誤期間系統調用,斷開的管道。

我解決了我的問題問題設置超時5分鐘的http連接或某些值超過60秒。如果我可以推薦如何解決你的問題在服務器Wireshark上運行,並用移動設備監聽通信。

4

我有使用DefaultHttpClient的相同問題,以及使用我自己的httpclient實現來支持https。小文件工作正常,大文件一次又一次地失敗。

閱讀此回覆後,我已經改變爲HttpsURLConnection喜歡接受的答案建議,也因爲它是由Android推薦(http://android-developers.blogspot.pt/2011/09/androids-http-clients.html)。

問題在於。原來問題出在服務器上,我已經改變了PHP服務器的配置以接受更大的尺寸,但我完全忘記了更改nginx的'client_max_body_size'。做出這個小改動後,發送大文件正在工作。通過HttpsUrlConnections和DefaultHttpClient。