HttpUrlConnection.openConnection第二次失败
我知道这个问题应该用System.setProperty(“http.keepAlive”,“false”)修复; openConnection之前,但这并不适用于我。首先尝试这个代码的作品,第二个失败。即使我在少于5秒后尝试这个请求,它也可以工作。如果我等待不止于此,它再次HttpUrlConnection.openConnection第二次失败
失败,这是我的代码:
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());
我得到最后一行除外:
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)
是否有人有什么这里是错的想法?。谢谢!
我解决了这个问题。在这里,我给你留下了代码,以防它可能对某人有所帮助。基本上我在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());
我相信你的问题在于你的代码的顺序。检查URLConnection JavaDocs中的那些方法 - 在mUrl.openConnection()上建立连接后,不应调用setRequestProperty。它可能是第一次工作,因为建立了连接,那么在下一次尝试建立连接之前,您正在更改不影响任何内容的设置。尝试使用HttpURLConnection构造函数,以便在设置属性后调用connect()。
感谢您的回答,但我担心这种方式行不通。这就是API文档所说的:URLConnection只能在实例化之后但连接到远程资源之前设置。 在我的情况下,实际连接的情况: conn.getInputStream() 和标题设置 – ggomeze 2010-07-29 06:08:30
当它保持连接活着使用HttpURLConnection
连接池被破坏,使得它试图使用已被服务器关闭连接。默认情况下,Android会在所有连接上设置KeepAlive。
System.setProperty("http.keepAlive", "false");
是禁用保持活动的所有连接,那么你避免在连接池的bug解决方法。
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());
谢谢@fonetik的答案和解释!我现在无法测试它,因为我转移到HttpClient,但我确信这可以帮助其他人。再次感谢! – ggomeze 2010-09-14 11:11:41
@ user464773'System.setProperty(“http.keepAlive”,“false”);'在应用程序的所有连接上禁用_Keep Alive_。这是我们想要的,因为_Keep Alive_将始终导致错误。使用'conn.setRequestProperty(“connection”,“close”);''只为''conn'禁用_Keep Alive_,当我们忘记将它添加到任何一个连接时,就会打开一扇门。我不知道这个bug是否会让它回到和谐之中,但Android团队知道它:http://code.google.com/p/android/issues/detail?id=7786 – barrycburton 2010-10-25 22:13:23
谢谢,这就是我正在寻找 – TacoEater 2013-02-20 01:23:01
你不需要的System.setProperty("http.keepAlive", "false");
所有你需要的是conn.setRequestProperty("connection", "close");
这能解决问题,但有效地杀死保持活动,因此可能使多个连接慢(这是一种耻辱)。我正在浏览和谐错误跟踪器,但无法找到任何东西。
@fonetik,你知不知道这是否已经与和谐长大的吗?我的意思不是说它帮助很大,因为另一个http相关的luni缺陷在超过一个月后仍然未被分配。
conn.setRequestProperty(“connection”,“close”);为我工作。简单而有效。我正在为Android L和M使用URLconnection。 – Josh 2015-12-16 13:31:21
这个bug已经固定在Android2.3版本中,因为我们知道System.setProperty("http.keepAlive", "false");
不是一个很好的解决方案,因为在移动设备上,创建每个连接是每次都是高成本的。
当我试图打开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
。
谷歌现在推荐使用HttpURLConnection的,因为一些这些错误的(从姜饼开始)之后,这已得到修复: HTTP:// android-developers.blogspot.com/2011/09/androids-http-clients.html – 2011-11-07 23:20:39
这个解决方案为什么解决这个问题? – 2012-04-11 11:38:51
迟早,特别是随着Android M的不断增长,HttpClient正在变得有效的弃用。建议URLConnection适用于未来很长时间的应用程序。 – Josh 2015-12-16 12:52:26