2013-12-17 144 views
1

我在我的代码中使用URLConnection。我已将ReadTimeout设置为5秒,但不会生效。当我切换无线接入点时,IO Exception正在被称为immidiately。URLConnection不尊重ReadTimeout

URLConnection conn;  
conn = new URL(StringUrls[0]).openConnection(); 
conn.setReadTimeout(5000); 
in = conn.getInputStream(); 


     try { 
      len = in.read(buffer); 
      bufOutstream.write(buffer, 0, len); 
      bufOutstream.close(); 
     } catch (IOException e1) { 
      e1.printStackTrace(); 
         } 

IO例外:

12-17 12:41:35.332 12761-13268/com.app.example W/System.err﹕ java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:542) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at libcore.io.IoBridge.recvfrom(IoBridge.java:506) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:240) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at java.io.BufferedInputStream.read(BufferedInputStream.java:304) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at libcore.net.http.UnknownLengthHttpInputStream.read(UnknownLengthHttpInputStream.java:41) 
12-17 12:41:35.362 12761-13268/com.app.example W/System.err﹕ at java.io.InputStream.read(InputStream.java:163) 

回答

1

示例代码如下,

它会尝试最多20次来读取正确的数据。

如果一次发生异常,它只是在5秒后再次尝试。

private static int currentRetryCount = 0; 

public static void main(String[] args) throws InterruptedException { 
    retryRead(20); 
} 

public static void retryRead(int maxRetryCount) throws InterruptedException { 
    if (currentRetryCount <= maxRetryCount) { 
     try { 
      System.out.println("try count " + currentRetryCount); 
      URLConnection conn; 
      conn = new URL("").openConnection(); 
      conn.setReadTimeout(5000); 
      conn.getInputStream(); 
      // if nothing happens,it just return 
      return; 
     } catch (Exception e) { 
      // if exception raises,it will try again after 5 seconds 
      Thread.sleep(5000); 

      currentRetryCount++; 
      retryRead(maxRetryCount); 
     } 
    } 
} 
+0

虽然这并不能完全回答我的问题,但我决定接受它,因为它看起来像是一个合理的解决方法。 – Kristopher

0

也许你正在寻找setConnectTimeout

connectTimeout是建立连接的超时时间。
readTimeout是连接建立后从输入流中读取数据的超时时间。

此外,当您的Wifi关闭时立即得到IOException的原因是因为如果没有用于连接的活动媒体,连接会立即中止,无论超时如何。

+0

是的,我纠正了它。我只在这里犯了错误,而不是在我的“真实代码”中。我必须简化它才能在这里发布。 – Kristopher

+0

你试过把readTimeout和connectTimeout都放在一起吗? – SiN

+0

是的,我已经试过。 – Kristopher

0

你想要什么效果?你能显示更多的细节信息吗?

将ReadTimeOut设置为N秒并不意味着总读取时间将小于N秒。

这意味着两个数据包之间的最长时间(通过连接,您将获得大量数据包)。

例如,如果在N秒内没有可用数据,则会引发SocketTimeoutException。

+0

我想在互联网连接中断时“持有”URL连接。所以当它在这5秒内重新连接时,缓冲区读数将被重试。 – Kristopher

+0

我认为你可以在catch块中做你的恢复。如果发生异常,你可以睡眠线程N秒,然后尝试重新打开连接。 – oxygen

+0

是的,这是一种方式,但如果中断会多次发生会怎样?你可以发布示例代码(可能只是一个方案)你怎么看这个? – Kristopher