2011-11-08 44 views
9

tôi đưa ra yêu cầu POST trong ứng dụng của tôi và somtimes (nếu tôi có một số lượng lớn các dữ liệu bài viết), các lỗi sau xảy ra:SSL bị hỏng ống

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

trong khi thực hiện http.execute (httpost) trong mã phía dưới. Có ai biết cách tránh điều này không?

Tôi đã cố gắng sử dụng AndroidHttpClient, nhưng không thể tìm thấy một cách hợp lệ cho auth cơ bản Và tôi đã thử một HttpsUrlConnection, nhưng nhận được cùng một lỗi.

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; 
} 

chỉnh sửa: Các mã sau đây được sử dụng để tải file, nếu tôi cố gắng để tải lên tập tin nhỏ, mã làm việc, nhưng nếu các tập tin được lớn hơn, tôi nhận được lỗi đường ống bị hỏng. Sử dụng kết nối Internet nhanh hơn sẽ làm tăng kích thước tệp, có vẻ như đã xảy ra sự cố với thời gian cho đến khi máy chủ đặt lại kết nối.

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

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

+0

thx, nhưng đã thử, cùng một lỗi. Tôi sử dụng một proxy cho yêu cầu, nhưng trong ứng dụng WM của tôi nó không chạy mà không có lỗi, phải phụ thuộc vào hệ thống android – 2red13

Trả lời

1

Tôi đã không thể giải quyết vấn đề với DefaultHttpClient, AndroidHttpClient hoặc Tóm tắt, nhưng cuối cùng tìm ra giải pháp với HttpsUrlRequest Xác thực ant qua tiêu đề thay vì CredentielsService:

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

tôi đã có cùng lỗi. Vấn đề là trong thư viện Android đâu là sử dụng DefaultHttpClient đã được khoảng từ Android API cấp 1 và AndroidHttpClient đã có sẵn từ mức API Android 8. Đây là lỗi trong android https://code.google.com/p/android/issues/detail?id=8625

Vấn đề của tôi là: Giá trị mặc định timeout là 60 giây. Khi tôi chạy kết nối trong Wireshark. Nó đã được tạo ra cái bắt tay và anh ta đã chờ đợi trên ApplicationData, nhưng anh ta không nhận được nó như vậy sau khi hết thời gian gửi FIN và tôi đã có: javax.net.ssl.SSLException: Viết lỗi: ssl = 0x2f0610: Lỗi I/O trong khi cuộc gọi hệ thống, đường ống bị hỏng.

Tôi đã giải quyết được sự cố khi cài đặt sự cố khi kết nối http trên 5 phút hoặc giá trị nào đó dài hơn 60 giây. Nếu tôi có thể đề nghị cách giải quyết vấn đề của bạn chạy trên máy chủ Wireshark và nghe giao tiếp với thiết bị di động.

4

Tôi đã gặp vấn đề tương tự khi sử dụng DefaultHttpClient, tốt, bằng cách sử dụng triển khai httpclient của riêng mình để hỗ trợ https. Các tập tin nhỏ nó đã làm việc tốt và các tập tin lớn đã thất bại thời gian sau khi thời gian.

Sau khi đọc câu trả lời này, tôi đã thay đổi thành HttpsURLConnection như câu trả lời được chấp nhận đề xuất và cũng vì nó được đề xuất bởi android (http://android-developers.blogspot.pt/2011/09/androids-http-clients.html).

Sự cố đã xảy ra. Hóa ra vấn đề là trên máy chủ, tôi đã thay đổi các cấu hình từ máy chủ PHP trước để chấp nhận kích thước lớn hơn, nhưng tôi hoàn toàn quên thay đổi 'client_max_body_size' của nginx. Sau khi thực hiện thay đổi nhỏ đó, các tệp lớn đang hoạt động. Thông qua cả HttpsUrlConnections và DefaultHttpClient.

Các vấn đề liên quan