Android:使用HttpsUrlConnection上传并获得响应,但得到了SocketTimeoutException

时间:2015-09-18 08:42:20

标签: android ssl https httpsurlconnection socket-timeout-exception

我有一个带SSL证书的服务器。
我正在使用函数uploadFileHttps(...)上传图像并通过HttpsUrlConnection获得相应的响应。
对于上传部分,它通过输出流发送图像数据 但是,服务器尚未收到该图像。
另外,当它试图通过输入流从服务器获得响应时。 它捕获异常“java.net.SocketTimeoutException:read timed out”
我怎么能解决它?

private static final int CONNECTION_TIMEOUT = 20000;
private static final int IMAGE_UPLOAD_TIMEOUT = 60000;

private void uploadFileHttps(File file, String requestURL) {
    HttpsURLConnection connection = null;
    try {

        //requestURL is a https link like: https://test.abcde.com/upload
        connection = (HttpsURLConnection) new URL(requestURL).openConnection();

        connection.setHostnameVerifier(new NullHostNameVerifier());

        connection.setConnectTimeout(CONNECTION_TIMEOUT);//timeout for handshake
        connection.setReadTimeout(IMAGE_UPLOAD_TIMEOUT);//timeout for waiting read data
        connection.setRequestMethod("PUT");
        connection.setRequestProperty("Content-Type", "image/jpeg");
        Token.setAuthTokenHeader(connection, context);

        connection.setDoOutput(true);//set to use httpURLConnection for output
        connection.connect();

        //upload file to server
        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
        int bytesRead;
        byte buf[] = new byte[1024];
        BufferedInputStream bufInput = new BufferedInputStream(new FileInputStream(file));
        while ((bytesRead = bufInput.read(buf)) != -1) {
            // write output
            out.write(buf, 0, bytesRead);
            out.flush();
        }
        out.flush();
        out.close();

        //get response from server
        BufferedReader br = new BufferedReader(new InputStreamReader((connection.getInputStream())));
        StringBuilder sb = new StringBuilder();
        String output;
        while ((output = br.readLine()) != null) {
            sb.append(output);
        }
        System.out.println(sb.toString());
    } catch (Exception e) {
        if (e != null)
            e.printStackTrace();
    } finally {
        if (connection != null) connection.disconnect();
    }
}

class NullHostNameVerifier implements HostnameVerifier {

    @Override
    public boolean verify(String hostname, SSLSession session) {
        Log.i("RestUtilImpl", "Approving certificate for " + hostname);
        return true;
    }

}

错误的堆栈跟踪

W/System.err﹕ java.net.SocketTimeoutException: Read timed out
W/System.err﹕ at com.android.org.conscrypt.NativeCrypto.SSL_read(Native Method)
W/System.err﹕ at com.android.org.conscrypt.OpenSSLSocketImpl$SSLInputStream.read(OpenSSLSocketImpl.java:689)
W/System.err﹕ at java.io.InputStream.read(InputStream.java:162)
W/System.err﹕ at java.io.BufferedInputStream.fillbuf(BufferedInputStream.java:142)
W/System.err﹕ at java.io.BufferedInputStream.read(BufferedInputStream.java:227)
W/System.err﹕ at com.android.okhttp.internal.Util.readAsciiLine(Util.java:316)
W/System.err﹕ at com.android.okhttp.internal.http.RawHeaders.fromBytes(RawHeaders.java:308)
W/System.err﹕ at com.android.okhttp.internal.http.HttpTransport.readResponseHeaders(HttpTransport.java:135)
W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.readResponse(HttpEngine.java:644)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:347)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
W/System.err﹕ at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:246)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.uploadFileSSL(HttpRequestTask.java:355)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.doRequest(HttpRequestTask.java:152)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.doInBackground(HttpRequestTask.java:182)
W/System.err﹕ at com.seasonworkstation.testhttps.network.HttpRequestTask.doInBackground(HttpRequestTask.java:47)
W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
W/System.err﹕ at java.lang.Thread.run(Thread.java:841)

1 个答案:

答案 0 :(得分:0)

extern BOOL isBitAtIndexOne(unsigned long number, NSInteger bit);
inline BOOL isBitAtIndexOne(unsigned long number, NSInteger bit) {
    return (BOOL)(number & (1 << bit));
}

这会将请求方法设置为connection.setRequestMethod("PUT");

PUT

这会将请求方法设置为connection.setDoOutput(true);//set to use httpURLConnection for output 。您需要在上面的POST行之前执行此