我正在编写一个 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