我的问题相当简单。如果网络连接丢失,我的程序需要立即通知。我使用的是Java 5,因此我无法使用NetworkInterface的非常方便的功能。
目前,我有两种不同的方法来检查网络连接:
(try..catches删除)
方法一:
URL url = new URL("http://www.google.com");
HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();
// trying to retrieve data from the source. If offline, this line will fail:
Object objData = urlConnect.getContent();
return true;
方法2:
Socket socket = new Socket("www.google.com", 80);
netAccess = socket.isConnected();
socket.close();
return netAccess;
但是,这两种方法都会阻塞,直到达到超时才返回false。我需要一个立即返回的方法,但与Java 5兼容。
谢谢!
编辑: 我忘了提到我的程序依赖于IP地址,而不是DNS名称。因此在解析主机时检查错误......
第二次编辑:
使用NetworkInterface找出最终解决方案:
Enumeration<NetworkInterface> eni = NetworkInterface.getNetworkInterfaces();
while(eni.hasMoreElements()) {
Enumeration<InetAddress> eia = eni.nextElement().getInetAddresses();
while(eia.hasMoreElements()) {
InetAddress ia = eia.nextElement();
if (!ia.isAnyLocalAddress() && !ia.isLoopbackAddress() && !ia.isSiteLocalAddress()) {
if (!ia.getHostName().equals(ia.getHostAddress()))
return true;
}
}
}
答案 0 :(得分:10)
来自JGuru
从Java 5开始,中有一个isReachable()方法 InetAddress类。您可以指定超时或 要使用的NetworkInterface。有关底层的更多信息 ping使用的Internet控制消息协议(ICMP),请参阅RFC 792 (http://www.faqs.org/rfcs/rfc792.html)。
Java2s的用法
int timeout = 2000;
InetAddress[] addresses = InetAddress.getAllByName("www.google.com");
for (InetAddress address : addresses) {
if (address.isReachable(timeout))
System.out.printf("%s is reachable%n", address);
else
System.out.printf("%s could not be contacted%n", address);
}
如果要避免阻塞,请在java.nio包中使用Java NIO(非阻塞IO)
String host = ...;
InetSocketAddress socketAddress = new InetSocketAddress(host, 80);
channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(socketAddress);
答案 1 :(得分:3)
运气不好。您无法通过TCP / IP立即获得通知。它充满了缓冲,重试和超时,因此它不会立即执行任何,并且TCP设计中没有任何与“拨号音”相对应的内容,也没有任何API。检测丢失连接的唯一方法是尝试对其进行I / O操作。如果是网络连接,我的程序需要立即通知 丢失。
我正在使用Java 5,所以我无法使用非常方便的功能 的NetworkInterface。
他们也不会帮助你。所有他们都可以告诉你的是网卡是上升还是下降,与你与更广阔世界的联系状态无关。
URL url = new URL("http://www.google.com");
HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();
// trying to retrieve data from the source. If offline, this line will fail:
Object objData = urlConnect.getContent();
return true;
如果您处于离线状态,则会因DNS失败而超时。
Socket socket = new Socket("www.google.com", 80);
netAccess = socket.isConnected();
socket.close();
return netAccess;
同上。但是,即使它没有,socket.isConnected()也总是返回true。那些API,如isConnected(),isBound(),isClosed(),只告诉你你对套接字做了什么。他们没有告诉你关于状态的任何信息连接。他们不能,因为我给出了上述原因。
如果发生异常,您忘记关闭套接字,因此您有资源泄漏。
我需要一种能立即返回的方法。
由于给出的理由不可能。你需要重新设计这个功能不存在的实现。
答案 2 :(得分:2)
您需要先创建名为interface
的{{1}},例如
NetworkListener
接下来,创建一个类并将其称为public interface NetworkListener {
public void sendNetworkStatus(String status);
}
,例如
NetworkStatusThread
然后在您的实例化public class NetworkStatusThread implements Runnable {
List listenerList = new Vector();
@SuppressWarnings("unchecked")
public synchronized void addNetworkListener(NetworkListener nl) {
listenerList.add(nl);
}
public synchronized void removeNetworkListener(NetworkListener nl) {
listenerList.remove(nl);
}
private synchronized void sendNetworkStatus(String status) {
// send it to subscribers
@SuppressWarnings("rawtypes")
ListIterator iterator = listenerList.listIterator();
while (iterator.hasNext()) {
NetworkListener rl = (NetworkListener)iterator.next();
rl.sendNetworkStatus(status);
}
}
public void run() {
while (true) {
System.out.println("Getting resource status");
try {
Thread.sleep(2000);
System.out.println("Sending resource status to registered listeners");
this.sendResourceStatus("OK");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
的类中,执行以下操作:
Thread
此外,在该课程中,您需要NetworkStatusThread netStatus = new NetworkStatusThread();
netStatus.addNetworkListener(this);
Thread t = new Thread(netStatus);
t.Start();
implement
,才能获得回调。
在上面的NetworkListener
方法中,您可以通过@Ali实现代码,但是可以通过我的状态:
run()
答案 3 :(得分:0)
您是否尝试过发布DNS解析?
您可以尝试:
public static InetAddress[] getAllByName(String host)
但我不确定这是否也需要超时..