8

[Java 1.5;日食伽利略]

调用 getInputStream() 方法时,HttpsURLConnection 似乎停止了。我尝试使用不同的网站无济于事(目前为https://www.google.com)。我应该指出我正在使用 http S

下面的代码已根据我从其他 StackOverflow 答案中学到的内容进行了修改。但是,到目前为止,我尝试过的任何解决方案都没有奏效。

我将非常感谢您朝正确的方向轻推:)

public static void request( URL url, String query ) 
{
try{

    HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

    //connection.setReadTimeout( 5000 ); //<-- uncommenting this line at least allows a timeout error to be thrown

    connection.setDoInput(true); 
    connection.setDoOutput(true);
    connection.setUseCaches(false);  
    System.setProperty("http.keepAlive", "false");


    connection.setRequestMethod( "POST" );


    // setting headers
    connection.setRequestProperty("Content-length",String.valueOf (query.length()));
    connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); //WAS application/x-www- form-urlencoded
    connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigExt)");

    ////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////
    System.out.println( "THIS line stalls" + connection.getInputStream() );
    ////////////////////////////////////////////////////////////////////////////////////

}catch( Exception e ) {
    System.out.println( e ); 
    e.printStackTrace(); 
}

典型错误如下所示:

java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293)
at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:782)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:739)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:256)
at java.io.BufferedInputStream.read(BufferedInputStream.java:313)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:681)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:626)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:983)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
at https_understanding.HTTPSRequest.request(HTTPSRequest.java:60)
at https_understanding.Main.main(Main.java:17)
4

3 回答 3

5
connection.setDoOutput(true);

这意味着您必须在尝试从其输入流中读取之前打开、写入和关闭连接的输出流。请参阅文档

于 2010-02-17T03:37:03.607 回答
3

我在 Android 2.2 中重现了该问题:通过无线和 HTTPS URL 从网络服务器下载时,错误是 URLConnection.getInputStream() 处的套接字“读取超时”

要修复它,请将 url.openStream() 用于 InputStream 而不是 connection.getInputStream()

奖励:您可以获得正在下载的文件的长度,以便显示完成百分比指示器

代码示例:

private final int TIMEOUT_CONNECTION = 5000;//5sec
private final int TIMEOUT_SOCKET = 30000;//30sec

file = new File(strFullPath);
URL url = new URL(strURL);
URLConnection ucon = url.openConnection();

//this timeout affects how long it takes for the app to realize there's a connection problem
ucon.setReadTimeout(TIMEOUT_CONNECTION);
ucon.setConnectTimeout(TIMEOUT_SOCKET);


//IMPORTANT UPDATE:
// ucon.getInputStream() often times-out over wireless
// so, replace it with ucon.connect() and url.openStream()
ucon.connect();
iFileLength = ucon.getContentLength();//returns -1 if not set in response header

if (iFileLength != -1)
{
    Log.i(TAG, "Expected Filelength = "+String.valueOf(iFileLength)+" bytes");
}

//Define InputStreams to read from the URLConnection.
// uses 5KB download buffer
InputStream is = url.openStream();//ucon.getInputStream();
BufferedInputStream inStream = new BufferedInputStream(is, 1024 * 5);
outStream = new FileOutputStream(file);
bFileOpen = true;
byte[] buff = new byte[5 * 1024];

//Read bytes (and store them) until there is nothing more to read(-1)
int total=0;
int len;
int percentdone;
int percentdonelast=0;
while ((len = inStream.read(buff)) != -1)
{
    //write to file
    outStream.write(buff,0,len);

    //calculate percent done
    if (iFileLength != -1)
    {
        total+=len;
        percentdone=(int)(total*100/iFileLength);

        //limit the number of messages to no more than one message every 10%
        if ( (percentdone - percentdonelast) > 10)
        {
            percentdonelast = percentdone;
            Log.i(TAG,String.valueOf(percentdone)+"%");
        }
    }
}

//clean up
outStream.flush();//THIS IS VERY IMPORTANT !
outStream.close();
bFileOpen = false;
inStream.close();
于 2011-12-16T00:26:50.033 回答
2

也不要设置内容长度标头。Java 将为您做到这一点。

于 2010-02-17T23:17:29.237 回答