2008-09-17 6 views
66

Я получаю ConnectException: Connection timed out с некоторой частотой от моего кода. URL, который я пытаюсь ударить, вверх. Один и тот же код работает для некоторых пользователей, но не для других. Кажется, что, как только один пользователь начинает получать это исключение, они продолжают получать исключение.Зачем возникает ошибка «java.net.ConnectException: Connection timed out», когда URL-адрес вверх?

Вот трассировки стека:

java.net.ConnectException: Connection timed out 
Caused by: java.net.ConnectException: Connection timed out 
    at java.net.PlainSocketImpl.socketConnect(Native Method) 
    at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333) 
    at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195) 
    at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182) 
    at java.net.Socket.connect(Socket.java:516) 
    at java.net.Socket.connect(Socket.java:466) 
    at sun.net.NetworkClient.doConnect(NetworkClient.java:157) 
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:365) 
    at sun.net.www.http.HttpClient.openServer(HttpClient.java:477) 
    at sun.net.www.http.HttpClient.<init>(HttpClient.java:214) 
    at sun.net.www.http.HttpClient.New(HttpClient.java:287) 
    at sun.net.www.http.HttpClient.New(HttpClient.java:299) 
    at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(HttpURLConnection.java:796) 
    at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:748) 
    at sun.net.www.protocol.http.HttpURLConnection.connect(HttpURLConnection.java:673) 
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:840) 

Вот отрывок из моего кода:

URLConnection urlConnection = null; 
OutputStream outputStream = null; 
OutputStreamWriter outputStreamWriter = null; 
InputStream inputStream = null; 

try { 
    URL url = new URL(urlBase); 
    urlConnection = url.openConnection(); 
    urlConnection.setDoOutput(true); 

    outputStream = urlConnection.getOutputStream(); // exception occurs on this line 
    outputStreamWriter = new OutputStreamWriter(outputStream); 
    outputStreamWriter.write(urlString); 
    outputStreamWriter.flush(); 
    inputStream = urlConnection.getInputStream(); 
    String response = IOUtils.toString(inputStream); 
    return processResponse(urlString, urlBase, response); 
} catch (IOException e) { 
    throw new Exception("Error querying url: " + urlString, e); 
} finally { 
    IoUtil.close(inputStream); 
    IoUtil.close(outputStreamWriter); 
    IoUtil.close(outputStream); 
} 
+7

Пожалуйста, отметьте один ответ как ACCPETED если вы решили свою проблему :) – Tobias

ответ

0

Существует вероятность того, что ваш IP/хоста блокировано удаленным хостом, особенно если он думает, что вы слишком сильно ударяете его.

67

таймауты подключения (при условии, локальная сеть и несколько клиентских машин), как правило, в результате

а) какое-то брандмауэр на пути, который просто съедает пакеты, не сообщая об отправителе вещи, как «Нет маршрут к хосту»

б) потери пакетов из-за неправильной конфигурации сети или линии перегрузки

с) слишком много запросов перегрузки сервера

г) небольшое количество одновременно доступных потоков/процессов O n сервер, который приводит к их удалению. Это происходит, в частности, с запросами, которые требуют много времени для запуска и могут сочетаться с c).

Надеюсь, это поможет.

+4

(d) - это только частный случай (c). – EJP

29

Если URL-адрес работает в браузере на одном компьютере, возможно, Java-код не использует прокси-сервер HTTP, используемый браузером для подключения к URL-адресу.

6

Я бы рекомендовал повысить время ожидания подключения до получения выходного потока, например, так:

urlConnection.setConnectTimeout(1000); 

Где 1000 в миллисекундах (1000 миллисекунд = 1 секунда).

+12

Это не поднимает его, это резко снижает его. По умолчанию это около минуты, и вы * не можете * увеличить его, вы можете только опустить его. – EJP

3
  • пытаются сделать Telnet, чтобы увидеть какой-либо вопрос брандмауэра
  • выполнить tracert/traceroute найти число переходов
1

Это может быть проблемой IPv6 (хост публикует IPv6 AAAA-адрес и хост-пользователи считают, что он настроен для IPv6, но на самом деле он неправильно подключен). Это также может быть проблема MTU сети, блок брандмауэра, или целевой хост может публиковать различные IP-адреса (случайно или на основе страны-источника), которые не все доступны. Или аналогичные сетевые проблемы.

Вы не можете много сделать, кроме того, чтобы установить тайм-аут и добавить хорошие сообщения об ошибках (особенно распечатывать разрешенный адрес хоста). Если вы хотите сделать его более надежным, добавьте повторную попытку, параллельную попытку всех адресов, а также посмотрите на кеширование имен (положительное и отрицательное) на платформе Java.

0

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

Убедитесь, что сервер разрешает использовать свой собственный IP-адрес или что вы передаете вещи из удаленного URL-адреса, который действительно существует.

2

В сообщении об ошибке говорится все: время ожидания подключения. Это означает, что ваш запрос не получил ответа в течение некоторого (по умолчанию) таймфрейма. Причины, по которым не было получено никакого ответа, вероятно, будет один из:

а) IP/домен или неправильный порт

б) IP/домен или порт (то есть услуга) вниз

с) IP/домен занимает больше времени, чем ваш тайм-аут по умолчанию, чтобы ответить

d) у вас есть брандмауэр, который блокирует запросы или ответы на любой порт, который вы используете

е) у вас есть брандмауэр, блокирующий запросы к этому конкретному хосту

е) Ваш доступ в Интернет вниз

г) Ваш живой сервер вниз т.е. в случае «покоя API вызова».

Обратите внимание, что брандмауэры и порт или IP-блокировка может быть на месте вашего провайдера

0

Я решил свою проблему с:

System.setProperty("https.proxyHost", "myProxy"); 
System.setProperty("https.proxyPort", "80"); 

или http.proxyHost ...