我需要使用SSL将压缩数据库(有效负载~10 MB)发送到PHP Web服务。
代码工作好几周,但我突然得到一个ssl broken pipe exception
(SSL Broken Pipe)。我没有看到任何错误原因 - 我没有更改代码,服务器配置仍然相同(IIS之前能够通过ssl处理数据传输)。
目前我使用的是java.net.HttpsURLConnection
(下面的代码) - 当您将文件从Android发送到网络服务时,您建议我使用哪种替代方案?似乎没有在设备上处理POST。
提前致谢
try {
final File compressedDb = new File(Environment.getExternalStorageDirectory() + "/" + Const.TMP_DIR + "/database.zip");
String sourceFileUri = compressedDb.getPath();
final long compressedDbSize = compressedDb.length();
float optimized = ((float) _dbSize / (float) compressedDbSize) * 100f;
int dbKb = (int) (((float) _dbSize) / 1024f);
int dbCompKb = (int) ((float) compressedDbSize / 1024f);
compressionInfo = getString(R.string.compression) + ": " +
dbKb + "kB " + getString(R.string.to) + " " + dbCompKb + "kB" + "<br>" +
getString(R.string.saved) + ": " + (int) optimized + "%" + "<br>";
Log.i(TAG, "DB name=" + compressedDb.getName() + " size=" + compressedDb.length() / 1024 + "kB.");
HttpsURLConnection connection;
DataOutputStream dos;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
File sourceFile = new File(sourceFileUri);
// int maxBufferSize = 1024 * 1024;
int maxBufferSize = (int) sourceFile.length();
if (sourceFile.isFile()) {
try {
// open a URL connection to the Servlet
FileInputStream fileInputStream = new FileInputStream(sourceFile);
url = new URL(params[0]);
connection = (HttpsURLConnection) url.openConnection();
connection.setDoInput(true); // Allow Inputs
connection.setUseCaches(false); // Don't use a Cached Copy
connection.setRequestMethod("POST");
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("ENCTYPE", "multipart/form-data");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
connection.setRequestProperty("the_database", sourceFileUri);
dos = new DataOutputStream(connection.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"the_database\";" +
"filename=\"" + sourceFileUri + "\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
int bytesTotal = bytesAvailable;
Log.i(TAG, "maxBuffer=" + maxBufferSize +
" | bytesTotal=" + bytesTotal + " | bytesAvailable=" + bytesAvailable);
while (bytesRead > 0) {
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream.read(buffer, 0, bufferSize);
int progress = 100 - (int) (((float) bytesAvailable * 100 / (float) bytesTotal));
publishProgress("" + progress);
}
// send multipart form data necessary after file data...
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
int serverResponseCode = connection.getResponseCode();
final String responseMessagePostDb = connection.getResponseMessage();
fileInputStream.close();
dos.flush();
dos.close();
if (responseMessagePostDb != null) {
responseStrings.add("<br>");
responseStrings.add("<b><u>" + getString(R.string.optimisation_string) + "</u></b>" + "<br>");
responseStrings.add(params[1]);
responseStrings.add("<b><u>" + getString(R.string.optimisation_database) + "</u></b>" + "<br>");
responseStrings.add(compressionInfo);
String response = (responseMessagePostDb.equals("OK") ? ("<font color=\"" + GREEN + "\">PASSED</font>") : "FAILED");
responseStrings.add(getString(R.string.server_response) + ": " + response);
return responseStrings;
}
} catch (Exception e) {
Log.e(TAG, "doInBackground: " + e.getMessage());
responseStrings.add("FAILED2"); // <- this exception is thrown
responseStrings.add(e.getMessage());
return responseStrings;
}
}
} catch (Exception ex) {
Log.e(TAG, "doInBackground: " + ex.getMessage());
responseStrings.add("FAILED3");
responseStrings.add(ex.getMessage());
return responseStrings;
}
Log.e(TAG, "doInBackground: " + "FAILED4");
responseStrings.add("FAILED4");
responseStrings.add("Unexpected Error...");
return responseStrings;
答案 0 :(得分:1)
如果您的代码到目前为止,那么从逻辑上讲,除非您的代码中存在争用条件,否则您不会看到不一致的结果,除非它不是代码。换句话说,如果服务器决定强制实施连接超时,那么您的代码似乎无理由地开始失败。甚至涉及SSL Broken Pipe异常的问题的链接似乎暗示原因是服务器,而不是客户端。
我的建议是尝试提出各种原因导致服务器执行不应该做的事情,然后通过更改代码来测试每个理论。换句话说,如果问题是超时问题,请对操作计时并通过网络发送较小的文件并验证是否有效。如果确实如此,那就有问题了。如果它没有,那么继续下一个理论。
不幸的是,上述代码没有问题,如果不了解更多详细信息,就会导致此问题无法解决。