2013-11-12 2 views
1

В моем приложении я открываю UrlConnections, и я устанавливаю время ожидания соединения. Иногда тайм-аута, но InputStream остается читаемым (и не содержат данных)ConnectTimeout не всегда блокирует чтение из входного потока?

Я успешно reproed это, используя следующий код:

System.setProperty("http.keepAlive", "false"); 

    long length = 0; 

    while (length == 0) { 
     HttpURLConnection connection = null; 
     try { 
      connection = (HttpURLConnection) (new URL("http://www.worldofwargraphs.com").openConnection()); 
      connection.setConnectTimeout(1); // 1ms 
      connection.connect(); 
     } catch (IOException ex) { 
      try { 
       byte[] buf = new byte[8196]; 
       try (InputStream is0 = connection.getInputStream(); InputStream is = new BufferedInputStream(is0, 8196)) { 
        if (is0 != null) { 
         int ret = 0; 
         while ((ret = is.read(buf)) > 0) { 
          length += ret; 
         } 
        } 
       } 
      } catch (IOException ex2) { 
       Logger.getLogger(JavaApplication6.class.getName()).log(Level.SEVERE, null, ex2); 
      } 
     } 
    } 

    System.out.println(length); 

Как вы можете видеть в этом коде, я стараюсь чтобы открыть соединение с небольшим таймаутом (1 мс), чтобы убедиться, что таймауты подключения. Тогда я стараюсь читать InputStream

Дело в том, что иногда при попытке чтения потока я получаю java.net.SocketTimeoutException: connect timed out (что я бы ожидать), но петля иногда заканчивается, показывая количество прочитанных байтов (32912)

Может ли кто-нибудь объяснить мне, почему это второе поведение иногда случается? Я попытался это сделать, но ничего не нашел об этом.

Благодаря

+0

Вы регистрируете 'ex' после того, как поймали' ex2'? – ZhongYu

+0

В этом примере нет необходимости, так как я использую 'ex2' для отображения, что я правильно получил исключение при попытке прочитать поток. 'ex' только здесь, чтобы войти в« catch »часть кода – Nisalon

+2

Я имею в виду, если вызывается' ex2', вы ошибочно выполняете 'log (ex)' вместо 'log (ex2)'. поэтому вы видите «время ожидания подключения» в журнале. – ZhongYu

ответ

0

Ваш смехотворно короткий таймаут соединения истекло, но соединение завершено впоследствии, так что вы могли читать. Обратите внимание, что установка таймаута соединения не устанавливает тайм-аут чтения, поэтому чтение блокируется до тех пор, пока данные не будут доступны.

EDIT: В любом случае ваш код является неправильным. Вы должны установить реалистичный тайм-аут подключения и закрыть сокет, если вы его получите. Продолжение чтения кода после исключения подключения не имеет никакого смысла.

+0

Я поставил этот таймаут, чтобы убедиться, что я повторите проблему, которую я наблюдаю в своей реальной программе. Но исключение иногда выбрасывается, а иногда нет (ex2) – Nisalon

+0

Либо, в зависимости от того, действительно ли соединение выполнено или нет. В любом случае ваш код неверен, см. Править. – EJP

Смежные вопросы