0

我正在编写一个 Java 程序,该程序在具有自定义 Linux 分布并使用 RESTful API 的嵌入式设备上运行。我希望即使 Internet 连接中断,该程序也能继续运行。

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

这是我的代码:

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,这是不可接受的。实际上,超时被忽略了。

[这里][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
4

0 回答 0