ti-enxame.com

Por que uma exceção "Java.net.ConnectException: Conexão expirada" quando o URL está ativo?

Estou recebendo um ConnectException: Connection timed out com alguma frequência do meu código. O URL que estou tentando atingir está ativo. O mesmo código funciona para alguns usuários, mas não para outros. Parece que uma vez que um usuário começa a receber essa exceção, ele continua recebendo a exceção.

Aqui está o rastreamento de pilha:

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)

Aqui está um trecho do meu código:

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);
}
79
Sarah Haskins

Tempo limite de conexão (assumindo uma rede local e várias máquinas clientes) normalmente

a) algum tipo de firewall no caminho que simplesmente come os pacotes sem dizer ao remetente coisas como "No Route to Host"

b) perda de pacotes devido a configuração incorreta da rede ou sobrecarga de linha

c) muitos pedidos sobrecarregando o servidor

d) um pequeno número de threads/processos disponíveis simultaneamente no servidor, o que faz com que todos sejam executados. Isso acontece especialmente com solicitações que demoram muito para serem executadas e podem ser combinadas com c).

Espero que isto ajude.

77
Jumpy

Se a URL funcionar bem no navegador da Web na mesma máquina, pode ser que o código Java não esteja usando o proxy HTTP que o navegador está usando para se conectar à URL.

29
Alexander

Eu recomendaria aumentar o tempo limite de conexão antes de obter o fluxo de saída, assim:

urlConnection.setConnectTimeout(1000);

Onde 1000 está em milissegundos (1000 milissegundos = 1 segundo).

5
Powerlord

A mensagem de erro diz tudo: sua conexão expirou. Isso significa que sua solicitação não obteve uma resposta dentro de algum período de tempo (padrão). As razões que nenhuma resposta foi recebida é provável que seja uma de:

a) O IP/domínio ou porta está incorreto

b) O IP/domínio ou porta (ou seja, serviço) está inativo

c) O IP/domínio está demorando mais do que o seu tempo limite padrão para responder

d) Você tem um firewall que está bloqueando solicitações ou respostas em qualquer porta que você esteja usando

e) Você tem um firewall que está bloqueando solicitações para esse host específico

f) Seu acesso à internet está inativo

g) Seu servidor ativo está inativo, ou seja, no caso de "chamada de API de descanso".

Observe que os firewalls e a porta ou o bloqueio de IP podem ser implementados pelo seu ISP.

4
M Hamza Javed
  • tente fazer o Telnet para ver qualquer problema de firewall
  • execute tracert/traceroute para encontrar o número de Hops
3
shahbaz sikander

Eu resolvi meu problema com:

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

ou http.proxyHost...

2
NikNik

Isso pode ser um problema de IPv6 (o host publica um endereço AAAA IPv6 e o ​​host de usuários acha que está configurado para IPv6, mas na verdade não está conectado corretamente). Isso também pode ser um problema de MTU de rede, um bloco de firewall ou o host de destino pode publicar endereços IP diferentes (aleatoriamente ou com base no país de criadores) que não podem ser acessados. Ou problemas de rede similliar.

Você não pode fazer muito além de definir um tempo limite e adicionar boas mensagens de erro (especialmente imprimir o endereço resolvido dos hosts). Se você quiser torná-lo mais robusto, adicione nova tentativa, teste paralelo de todos os endereços e também analise o cache de resolução de nomes (positivo e negativo) na plataforma Java.

1
eckes

Existe a possibilidade de o seu IP/Host ser bloqueado pelo Host remoto, especialmente se achar que você está acertando muito.

0
larsivi

A razão pela qual isso aconteceu comigo foi que um servidor remoto estava permitindo apenas determinados IPs endereçados mas não seus próprios, e eu estava tentando processar as imagens das URLs do servidor ... então tudo simplesmente pararia, exibindo o erro de tempo limite que você teve... 

Certifique-se de que o servidor esteja permitindo seu próprio IP ou que você esteja processando coisas de algum URL remoto que realmente existe.

0
Damir Olejar