Android 通过HTTPS POST将文件发送到远程

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将压缩数据库(有效负载~10 MB)发送到PHP web服务

这段代码运行了好几个星期,但我突然遇到了一个
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断管异常似乎暗示原因是服务器,而不是客户端

我的建议是尝试找出故障的各种原因,包括服务器做不应该做的事情,然后通过修改代码来测试每一种理论。换句话说,如果问题是超时的问题,则对操作进行计时,并通过网络发送一个较小的文件,并验证其是否有效。如果有效,则必须进行测试你的问题。如果没有,那么继续下一个理论

不幸的是,上述代码没有问题,这使得这个问题在不了解更多细节的情况下无法解决。

对于“您会推荐哪种替代方案”的问题,我选择的库是(对于许多开发人员而言)。