并不总是抛出java.net.SocketTimeoutException

时间:2015-04-10 13:18:01

标签: java httpurlconnection socket-timeout-exception

我正在使用自定义Linux dist和使用RESTful API编写在嵌入式设备上运行的Java程序。我希望即使互联网连接断开,这个程序也会继续运行。

为了确保这一点,我设置了一个指定的连接超时,但它似乎随机工作。

这是我的代码:

HttpURLConnection connection = null;
String query = String.format("key=%s&deviceId=%d", key, deviceId);
String response = "";

try
{
    URL requestUrl = new URL(REST_API_URL + api + "/?" + query);
    System.out.println("URL: " + requestUrl.toString());
    if ((connection = (HttpURLConnection) requestUrl.openConnection()) == null)
    {
        Log.severe("Cannot open HTTP connection.", null);
    }

    // Set HTTP options
    connection.setRequestMethod("GET");
    connection.setRequestProperty("Accept", "text/json");
    connection.setRequestProperty("Content-Type", "text/json");
    connection.setRequestProperty("Accept-Charset", CHARSET);
    connection.setConnectTimeout(2000);
    connection.setReadTimeout(2000);

    connection.connect();

    // Check if the response was OK
    if (connection.getResponseCode() != HttpURLConnection.HTTP_OK)
    {
        Log.severe("HTTP connection failed : " + connection.getResponseMessage(), null);
    }

    // Get the response stream
    InputStream input = connection.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
    response = reader.readLine();
}
catch (IOException e)
{
    Log.severe(e.getMessage(), e);
}
finally
{
    if (connection != null)
    {
        connection.disconnect();
    }
}

问题是如果我断开Internet,这会在一段时间(~20秒)之后抛出java.net.UnknownHostException,这是不可接受的。 实际上,超时被忽略了。

[here] [1]我已经读到,在某些Android设备上,HttpURLConnection类可能有问题。所以我也尝试使用org.apache.http.client.HttpClient,这是最糟糕的(我不得不用一种丑陋的语法安装一半已弃用的软件包)并且没有解决我的问题。

以下是具有最新类的代码:

String query = String.format("key=%s&deviceId=%d", key, deviceId);
String response = "";

try
{
    // Set HTTP parameters
    URI requestUri = new URI(REST_API_URL + api + "/?" + query);
    System.out.println("URL: " + requestUri.toString());

    RequestConfig requestConfig = RequestConfig.custom()
       .setSocketTimeout(2000)
       .setConnectTimeout(2000)
       .setConnectionRequestTimeout(2000)
       .build();

    HttpGet httpGet = new HttpGet(requestUri);
    httpGet.setConfig(requestConfig);
    httpGet.addHeader("Accept", "text/json");
    httpGet.addHeader("Content-Type", "text/json");

    // Create a client
    CloseableHttpClient httpClient = HttpClients.createDefault();

    // Run the HTTP request
    HttpResponse httpResponse = httpClient.execute(httpGet);

    // Check the response code
    if (httpResponse.getStatusLine().getStatusCode() != 200)
    {
        Log.severe("HTTP connection failed : " + httpResponse.getStatusLine().getReasonPhrase(), null);
    }

    // Get the response stream
    InputStreamReader input = new InputStreamReader(httpResponse.getEntity().getContent());
    BufferedReader reader = new BufferedReader(input);
    response = reader.readLine();

    // Release the connection
    httpClient.close();
}
catch (IOException | URISyntaxException e)
{
    Log.severe(e.getMessage(), e);
}

有什么想法吗?

修改

我在/etc/resolv.conf文件中添加了一个选项,为DNS查找设置超时但似乎也被忽略了。

这是我的resolv.conf文件:

search einet.ad.eivd.ch # eth0
nameserver 10.192.22.5 # eth0
nameserver 10.192.57.10 # eth0
options timeout:1

0 个答案:

没有答案