Android 通过HTTPS POST将文件发送到远程
我需要使用SSL将压缩数据库(有效负载~10 MB)发送到PHP web服务 这段代码运行了好几个星期,但我突然遇到了一个Android 通过HTTPS POST将文件发送到远程,android,ssl,https,file-transfer,Android,Ssl,Https,File Transfer,我需要使用SSL将压缩数据库(有效负载~10 MB)发送到PHP web服务 这段代码运行了好几个星期,但我突然遇到了一个ssl断管异常()。我看不出发生错误的任何原因-我没有更改代码,服务器配置仍然相同(IIS以前能够通过ssl处理数据传输) 目前我使用的是java.net.HttpsURLConnection(下面的代码)-当从Android向web服务发送文件时,您建议我使用哪种替代方法?似乎POST未在设备上处理 提前谢谢 try { final File compressedD
ssl断管异常
()。我看不出发生错误的任何原因-我没有更改代码,服务器配置仍然相同(IIS以前能够通过ssl处理数据传输)
目前我使用的是java.net.HttpsURLConnection
(下面的代码)-当从Android向web服务发送文件时,您建议我使用哪种替代方法?似乎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;
试试看{
final File compressedb=新文件(Environment.getExternalStorageDirectory()+“/”+Const.TMP_DIR+“/database.zip”);
字符串sourceFileUri=compressedDb.getPath();
最终长压缩尺寸=压缩长度();
浮点数优化=((浮点数)_dbSize/(浮点数)压缩dbSize)*100f;
intdbkb=(int)((浮点)dbSize)/1024f);
int dbCompKb=(int)((浮点)压缩dbsize/1024f);
compressionInfo=getString(R.string.compression)+“:”+
dbKb+“kB”+getString(R.string.to)+“”+dbCompKb+“kB”+“
”+
getString(R.string.saved)+“:”+(int)优化+“%”+“
”;
Log.i(标记“DB name=“+compressedDb.getName()+”size=“+compressedDb.length()/1024+”kB”);
httpsurl连接;
数据输出流dos;
字符串lineEnd=“\r\n”;
字符串双连字符=“--”;
字符串边界=“*******”;
int字节读取,字节可用,缓冲区大小;
字节[]缓冲区;
File sourceFile=新文件(sourceFileUri);
//int maxBufferSize=1024*1024;
int maxBufferSize=(int)sourceFile.length();
if(sourceFile.isFile()){
试一试{
//打开到Servlet的URL连接
FileInputStream FileInputStream=新的FileInputStream(sourceFile);
url=新url(参数[0]);
connection=(HttpsURLConnection)url.openConnection();
connection.setDoInput(true);//允许输入
connection.setUseCaches(false);//不要使用缓存副本
connection.setRequestMethod(“POST”);
setRequestProperty(“连接”,“保持活动”);
connection.setRequestProperty(“ENCTYPE”、“多部分/表单数据”);
connection.setRequestProperty(“内容类型”、“多部分/表单数据;边界=“+boundary”);
setRequestProperty(“_数据库”,sourceFileUri);
dos=新的DataOutputStream(connection.getOutputStream());
写字节(两个连字符+边界+行结束);
writeBytes(“内容处置:表单数据;名称=\“U数据库\;”+
“文件名=\”“+sourceFileUri+”\”“+lineEnd);
dos.writeBytes(lineEnd);
//创建最大大小的缓冲区
bytesAvailable=fileInputStream.available();
bufferSize=Math.min(字节可用,maxBufferSize);
buffer=新字节[bufferSize];
//读取文件并将其写入表单。。。
bytesRead=fileInputStream.read(缓冲区,0,缓冲区大小);
int bytesTotal=字节可用;
Log.i(标记“maxBuffer=“+maxBufferSize+
“|bytesTotal=“+bytesTotal+”|bytesavable=“+bytesavable”);
而(字节读取>0){
写入(缓冲区,0,缓冲区大小);
bytesAvailable=fileInputStream.available();
bufferSize=Math.min(字节可用,maxBufferSize);
bytesRead=fileInputStream.read(缓冲区,0,缓冲区大小);
int progress=100-(int)((浮点)字节可用*100/(浮点)字节总数));
出版进度(“+”进度);
}
//在文件数据之后发送所需的多部分表单数据。。。
dos.writeBytes(lineEnd);
写字节(两个连字符+边界+两个连字符+行结束);
//来自服务器的响应(代码和消息)
int serverResponseCode=connection.getResponseCode();
最终字符串responseMessagePostDb=connection.getResponseMessage();
fileInputStream.close();
dos.flush();
dos.close();
if(responseMessagePostDb!=null){
responseStrings.添加(“
”);
responseStrings.add(“+getString(R.string.Optimization_string)++”
”;
responseStrings.add(参数[1]);
responseStrings.add(“+getString(R.string.Optimization_数据库)++”+“
”);
responseStrings.add(压缩信息);
字符串响应=(responseMessagePostDb.equals(“确定”)?(“通过”):“失败”);
add(getString(R.string.server\u response)+“:”+response);
回报率;
}
}捕获(例外e){
Log.e(标记“doInBackground:+e.getMessage());
responseStrings.add(“失败2”);//如果您的代码运行到这一点,那么从逻辑上讲,除非您的代码中有竞争条件,否则您不会看到不一致的结果,除非它不是代码。换句话说,如果服务器决定强制连接超时,您的代码将开始毫无理由地失败。甚至连指向问题的链接都涉及到SSL断管异常似乎暗示原因是服务器,而不是客户端
我的建议是尝试找出故障的各种原因,包括服务器做不应该做的事情,然后通过修改代码来测试每一种理论。换句话说,如果问题是超时的问题,则对操作进行计时,并通过网络发送一个较小的文件,并验证其是否有效。如果有效,则必须进行测试你的问题。如果没有,那么继续下一个理论
不幸的是,上述代码没有问题,这使得这个问题在不了解更多细节的情况下无法解决。对于“您会推荐哪种替代方案”的问题,我选择的库是(对于许多开发人员而言)。