HttpUrlConnection.openConnection第二次失败

我知道这个问题应该用System.setProperty(“http.keepAlive”,“false”)修复; openConnection之前,但这并没有对我工作。 首先尝试这个代码的作品,第二个失败。 即使我不到5秒后尝试这个请求,它也可以。 如果我等多了,那就再次失败

这是我的代码:

System.setProperty("http.keepAlive", "false"); HttpURLConnection conn = (HttpURLConnection) mURL.openConnection(); conn.setUseCaches(false); conn.setRequestProperty("Connection","Keep-Alive"); conn.setRequestProperty("User-Agent", useragent); conn.setConnectTimeout (30000) ; conn.setDoOutput(true); conn.setDoInput(true); consumer.sign(conn); InputSource is = new InputSource(conn.getInputStream()); 

我在最后一行得到exception:

 java.io.IOException: Write error: I/O error during system call, Broken pipe W/System.err( 2164): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.nativewrite(Native Method) W/System.err( 2164): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.access$600(OpenSSLSocketImpl.java:55) W/System.err( 2164): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.write(OpenSSLSocketImpl.java:583) W/System.err( 2164): at java.io.OutputStream.write(OutputStream.java:82) W/System.err( 2164): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.sendRequest(HttpURLConnectionImpl.java:1332) W/System.err( 2164): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequestInternal(HttpURLConnectionImpl.java:1656) W/System.err( 2164): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.doRequest(HttpURLConnectionImpl.java:1649) W/System.err( 2164): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1153) W/System.err( 2164): at org.apache.harmony.luni.internal.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:253) 

有人知道这里有什么问题吗? 谢谢!

Solutions Collecting From Web of "HttpUrlConnection.openConnection第二次失败"

HttpURLConnection在保持连接活动时使用的连接池已损坏,因此它尝试使用服务器已closures的连接。 默认情况下,Android会在所有连接上设置KeepAlive。

System.setProperty("http.keepAlive", "false"); 是一种解决方法,为所有连接禁用KeepAlive,以避免连接池中的错误。

conn.setRequestProperty("Connection","Keep-Alive"); 为这个特定的连接打开KeepAlive,实质上颠倒了System.setProperty("http.keepAlive", "false"); 确实。

此外,我总是明确地调用connect() ,因为它清楚地表明了你的连接设置的结束位置。 我不确定是否调用这个方法是可选的。

 System.setProperty("http.keepAlive", "false"); HttpURLConnection conn = (HttpURLConnection) mURL.openConnection(); conn.setUseCaches(false); conn.setRequestProperty("User-Agent", useragent); conn.setConnectTimeout(30000); conn.setDoOutput(true); conn.setDoInput(true); consumer.sign(conn); conn.connect(); InputSource is = new InputSource(conn.getInputStream()); 

你不需要System.setProperty("http.keepAlive", "false");

所有你需要的是conn.setRequestProperty("connection", "close");

这解决了这个问题,但有效地杀死了活着,因此有可能使多个连接变慢(这是一个耻辱)。 我正在通过和谐错误跟踪器,但无法find任何东西。

@fonetik,你知道这是否已经和谐地提出来了吗? 我的意思不是说这样做很有帮助,因为另一个http相关的luni缺陷在一个多月后仍然没有分配。

我解决了这个问题。 在这里,我给你留下代码,以防某人对你有帮助。 基本上我在Google上看到使用HttpClient / HttpGet而不是HttpUrlConnection的趋势。 所以我尝试了这些类,一切工作:

 final HttpClient client = new DefaultHttpClient(); final HttpGet conn = new HttpGet(mURL.toString()); OAuthConsumer consumer = mOAuthManager.getPostConsumer(); consumer.sign(conn); HttpResponse response = client.execute(conn); InputSource is = new InputSource(response.getEntity().getContent()); 

我们知道System.setProperty("http.keepAlive", "false");这个bug已经在Android2.3版本中修复了System.setProperty("http.keepAlive", "false"); 并不是一个很好的解决scheme,因为在移动设备上,创build每个连接是每次都是高成本的。

我相信你的问题在于你的代码的顺序。 检查URLConnection JavaDocs中的那些方法 – 在mUrl.openConnection()上build立连接后,不应调用setRequestProperty。 它可能是第一次工作,因为连接已经完成,那么在下一次尝试build立连接之前,您正在更改不影响任何内容的设置。 尝试使用HttpURLConnection构造函数,以便您可以在设置属性后调用connect()。

当我试图打开https连接它工作正常,但第二次失败,因为我已经设置系统属性值而不是HttpsURLConnection连接。 我有java.io.IOException :写入错误:第二次打开https连接时发生I / O问题。 我在应用程序中使用了以下代码。

 System.setProperty("http.proxyHost", proxy); System.setProperty("http.proxyPort", port); 

但是,当我改变一样的下面,它工作正常。

 javax.net.ssl.HttpsURLConnection ucon = (javax.net.ssl.HttpsURLConnection) urlWPF.openConnection(proxyserver); ucon.setRequestProperty("http.proxyHost", proxy); ucon.setRequestProperty("http.proxyPort", port); 

如果您设置系统属性,它将适用于整个应用程序。 如果你想重置相同,你可以按照两种方式。 一个是你需要服务器刷新,第二个是你必须改变上面提到的HttpsURLConnection.setRequestProperty