如何在Java中检查互联网连接是否存在?

发布于 2024-08-04 11:47:32 字数 291 浏览 2 评论 0原文

如何检查是否可以通过java连接到互联网?一种方法是:

final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...

但是是否有更合适的方法来执行该任务,特别是如果您需要经常连续检查并且很可能会失去互联网连接?

How do you check if you can connect to the internet via java? One way would be:

final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
... if we got here, we should have net ...

But is there something more appropriate to perform that task, especially if you need to do consecutive checks very often and a loss of internet connection is highly probable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

一袭白衣梦中忆 2024-08-11 11:47:32

您应该连接到您的实际应用程序需要的地方。否则,您将测试是否与不相关的地方(本例中为 Google)有连接。

特别是,如果您尝试与 Web 服务通信,并且您控制着该 Web 服务,那么采用某种廉价的“获取状态”Web 方法将是一个好主意。这样您就可以更好地了解您的“真实”通话是否有效。

在其他情况下,只需打开与应打开的端口的连接就足够了 - 或者发送 ping。 InetAddress.isReachable很可能是满足您需求的合适 API。

You should connect to the place that your actual application needs. Otherwise you're testing whether you have a connection to somewhere irrelevant (Google in this case).

In particular, if you're trying to talk to a web service, and if you're in control of the web service, it would be a good idea to have some sort of cheap "get the status" web method. That way you have a much better idea of whether your "real" call is likely to work.

In other cases, just opening a connection to a port that should be open may be enough - or sending a ping. InetAddress.isReachable may well be an appropriate API for your needs here.

氛圍 2024-08-11 11:47:32

您基本上提供的代码加上对 connect 的调用就足够了。是的,可能只是 Google 不可用,但您需要联系的其他网站却可以访问,但这种可能性有多大?另外,此代码应该仅在您实际上无法访问外部资源时执行(在 catch 块中尝试找出失败的原因),所以我想说,如果您的感兴趣的外部资源 Google 不可用,您可能遇到网络连接问题。

private static boolean netIsAvailable() {
    try {
        final URL url = new URL("http://www.google.com");
        final URLConnection conn = url.openConnection();
        conn.connect();
        conn.getInputStream().close();
        return true;
    } catch (MalformedURLException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        return false;
    }
}

The code you basically provided, plus a call to connect should be sufficient. So yeah, it could be that just Google's not available but some other site you need to contact is on but how likely is that? Also, this code should only execute when you actually fail to access your external resource (in a catch block to try and figure out what the cause of the failure was) so I'd say that if both your external resource of interest and Google are not available chances are you have a net connectivity problem.

private static boolean netIsAvailable() {
    try {
        final URL url = new URL("http://www.google.com");
        final URLConnection conn = url.openConnection();
        conn.connect();
        conn.getInputStream().close();
        return true;
    } catch (MalformedURLException e) {
        throw new RuntimeException(e);
    } catch (IOException e) {
        return false;
    }
}
神爱温柔 2024-08-11 11:47:32

人们建议使用 INetAddress.isReachable。问题在于某些站点将其防火墙配置为阻止 ICMP Ping 消息。因此,即使 Web 服务可以访问,“ping”也可能会失败。

当然,反之亦然。即使网络服务器已关闭,主机也可能会响应 ping。

当然,由于本地防火墙的限制,计算机可能无法直接连接到某些(或所有)Web 服务器。

根本问题是“可以连接到互联网”是一个定义不明确的问题,如果没有

  1. 用户机器和“本地”网络环境的信息,以及
  2. 应用程序需要什么信息, 这种事情就很难测试。使用权。

因此,一般来说,最简单的解决方案是应用程序尝试访问它需要访问的任何内容,然后依靠人类智能来进行诊断。

People have suggested using INetAddress.isReachable. The problem is that some sites configure their firewalls to block ICMP Ping messages. So a "ping" might fail even though the web service is accessible.

And of course, the reverse is true as well. A host may respond to a ping even though the webserver is down.

And of course, a machine may be unable to connect directly to certain (or all) web servers due to local firewall restrictions.

The fundamental problem is that "can connect to the internet" is an ill-defined question, and this kind of thing is difficult to test without:

  1. information on the user's machine and "local" networking environment, and
  2. information on what the app needs to access.

So generally, the simplest solution is for an app to just try to access whatever it needs to access, and fall back on human intelligence to do the diagnosis.

荒人说梦 2024-08-11 11:47:32

这段代码应该可靠地完成这项工作。

请注意,使用 try-with-resources声明我们不需要关闭资源。

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class InternetAvailabilityChecker
{
    public static boolean isInternetAvailable() throws IOException
    {
        return isHostAvailable("google.com") || isHostAvailable("amazon.com")
                || isHostAvailable("facebook.com")|| isHostAvailable("apple.com");
    }

    private static boolean isHostAvailable(String hostName) throws IOException
    {
        try(Socket socket = new Socket())
        {
            int port = 80;
            InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
            socket.connect(socketAddress, 3000);

            return true;
        }
        catch(UnknownHostException unknownHost)
        {
            return false;
        }
    }
}

This code should do the job reliably.

Note that when using the try-with-resources statement we don't need to close the resources.

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;

public class InternetAvailabilityChecker
{
    public static boolean isInternetAvailable() throws IOException
    {
        return isHostAvailable("google.com") || isHostAvailable("amazon.com")
                || isHostAvailable("facebook.com")|| isHostAvailable("apple.com");
    }

    private static boolean isHostAvailable(String hostName) throws IOException
    {
        try(Socket socket = new Socket())
        {
            int port = 80;
            InetSocketAddress socketAddress = new InetSocketAddress(hostName, port);
            socket.connect(socketAddress, 3000);

            return true;
        }
        catch(UnknownHostException unknownHost)
        {
            return false;
        }
    }
}
樱桃奶球 2024-08-11 11:47:32

如果您使用的是 java 6,可以使用 NetworkInterface 检查可用的网络接口。
即是这样的:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
  NetworkInterface interf = interfaces.nextElement();
  if (interf.isUp() && !interf.isLoopback())
    return true;
}

我自己还没有尝试过。

If you're on java 6 can use NetworkInterface to check for available network interfaces.
I.e. something like this:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
  NetworkInterface interf = interfaces.nextElement();
  if (interf.isUp() && !interf.isLoopback())
    return true;
}

Haven't tried it myself, yet.

幼儿园老大 2024-08-11 11:47:32

此代码:

"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());

如果离线,则返回 - 给我 - true,否则返回 false。 (嗯,我不知道这是否适用于所有计算机)。

这比上面的其他方法要快得多。


编辑:我发现只有当用于互联网连接的“翻转开关”(在笔记本电脑上)或其他一些系统定义的选项关闭时,这才有效。也就是说,系统本身知道不寻找任何 IP 地址。

This code:

"127.0.0.1".equals(InetAddress.getLocalHost().getHostAddress().toString());

Returns - to me - true if offline, and false, otherwise. (well, I don't know if this true to all computers).

This works much faster than the other approaches, up here.


EDIT: I found this only working, if the "flip switch" (on a laptop), or some other system-defined option, for the internet connection, is off. That's, the system itself knows not to look for any IP addresses.

这个俗人 2024-08-11 11:47:32

如果存在互联网连接,InetAddress.isReachable有时会返回 false。

在 java 中检查互联网可用性的另一种方法是:此函数进行真正的 ICMP ECHO ping。

public static boolean isReachableByPing(String host) {
     try{
                String cmd = "";
                if(System.getProperty("os.name").startsWith("Windows")) {   
                        // For Windows
                        cmd = "ping -n 1 " + host;
                } else {
                        // For Linux and OSX
                        cmd = "ping -c 1 " + host;
                }

                Process myProcess = Runtime.getRuntime().exec(cmd);
                myProcess.waitFor();

                if(myProcess.exitValue() == 0) {

                        return true;
                } else {

                        return false;
                }

        } catch( Exception e ) {

                e.printStackTrace();
                return false;
        }
}

InetAddress.isReachable sometime return false if internet connection exist.

An alternative method to check internet availability in java is : This function make a real ICMP ECHO ping.

public static boolean isReachableByPing(String host) {
     try{
                String cmd = "";
                if(System.getProperty("os.name").startsWith("Windows")) {   
                        // For Windows
                        cmd = "ping -n 1 " + host;
                } else {
                        // For Linux and OSX
                        cmd = "ping -c 1 " + host;
                }

                Process myProcess = Runtime.getRuntime().exec(cmd);
                myProcess.waitFor();

                if(myProcess.exitValue() == 0) {

                        return true;
                } else {

                        return false;
                }

        } catch( Exception e ) {

                e.printStackTrace();
                return false;
        }
}
不乱于心 2024-08-11 11:47:32

我通常将其分为三个步骤。

  1. 我首先看看是否可以将域名解析为IP地址。
  2. 然后我尝试通过 TCP(端口 80 和/或 443)进行连接并正常关闭。
  3. 最后,我将发出一个 HTTP 请求并检查是否有 200 响应返回。

如果在任何时候失败,我都会向用户提供适当的错误消息。

I usually break it down into three steps.

  1. I first see if I can resolve the domain name to an IP address.
  2. I then try to connect via TCP (port 80 and/or 443) and close gracefully.
  3. Finally, I'll issue an HTTP request and check for a 200 response back.

If it fails at any point, I provide the appropriate error message to the user.

与风相奔跑 2024-08-11 11:47:32
URL url=new URL("http://[any domain]");
URLConnection con=url.openConnection();

/*now errors WILL arise here, i hav tried myself and it always shows "connected" so we'll open an InputStream on the connection, this way we know for sure that we're connected to d internet */

/* Get input stream */
con.getInputStream();

将上述语句放在 try catch 块中,如果 catch 中出现异常,则表示没有建立互联网连接。 :-)

URL url=new URL("http://[any domain]");
URLConnection con=url.openConnection();

/*now errors WILL arise here, i hav tried myself and it always shows "connected" so we'll open an InputStream on the connection, this way we know for sure that we're connected to d internet */

/* Get input stream */
con.getInputStream();

Put the above statements in try catch blocks and if an exception in caught means that there's no internet connection established. :-)

叶落知秋 2024-08-11 11:47:32

使用 NetworkInterface 等待网络的代码对我有用,直到我从固定网络地址切换到 DHCP。一个轻微的增强使其还可以与 DHCP 一起使用:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
    NetworkInterface interf = interfaces.nextElement();
    if (interf.isUp() && !interf.isLoopback()) {
    List<InterfaceAddress> adrs = interf.getInterfaceAddresses();
    for (Iterator<InterfaceAddress> iter = adrs.iterator(); iter.hasNext();) {
        InterfaceAddress adr = iter.next();
        InetAddress inadr = adr.getAddress();
        if (inadr instanceof Inet4Address) return true;
            }
    }
}

这适用于 openSuse 13.1 中的 Java 7 for IPv4 网络。原始代码的问题在于,虽然接口从挂起恢复后已启动,但尚未分配 IPv4 网络地址。等待分配后,程序可以连接到服务器。但我不知道在 IPv6 的情况下该怎么办。

The code using NetworkInterface to wait for the network worked for me until I switched from fixed network address to DHCP. A slight enhancement makes it work also with DHCP:

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
    NetworkInterface interf = interfaces.nextElement();
    if (interf.isUp() && !interf.isLoopback()) {
    List<InterfaceAddress> adrs = interf.getInterfaceAddresses();
    for (Iterator<InterfaceAddress> iter = adrs.iterator(); iter.hasNext();) {
        InterfaceAddress adr = iter.next();
        InetAddress inadr = adr.getAddress();
        if (inadr instanceof Inet4Address) return true;
            }
    }
}

This works for Java 7 in openSuse 13.1 for IPv4 network. The problem with the original code is that although the interface was up after resuming from suspend, an IPv4 network address was not yet assigned. After waiting for this assignment, the program can connect to servers. But I have no idea what to do in case of IPv6.

一口甜 2024-08-11 11:47:32

1) 找出您的应用程序需要连接到的位置。

2) 设置工作进程来检查 InetAddress.isReachable 监视到该地址的连接。

1) Figure out where your application needs to be connecting to.

2) Set up a worker process to check InetAddress.isReachable to monitor the connection to that address.

说不完的你爱 2024-08-11 11:47:32

此代码包含在我用来测试连接是否可用的 jUnit 测试类中。我总是收到连接,但如果您检查内容长度,如果未知,它应该为 -1:

  try {
    URL url = new URL("http://www.google.com");
    URLConnection connection = url.openConnection();

    if(connection.getContentLength() == -1){
          fail("Failed to verify connection");
    }
  } 
  catch (IOException e) {
      fail("Failed to open a connection");
      e.printStackTrace();
  }

This code is contained within a jUnit test class I use to test if a connection is available. I always receive a connection, but if you check the content length it should be -1 if not known :

  try {
    URL url = new URL("http://www.google.com");
    URLConnection connection = url.openConnection();

    if(connection.getContentLength() == -1){
          fail("Failed to verify connection");
    }
  } 
  catch (IOException e) {
      fail("Failed to open a connection");
      e.printStackTrace();
  }
淡忘如思 2024-08-11 11:47:32
public boolean checkInternetConnection()
{
     boolean status = false;
     Socket sock = new Socket();
     InetSocketAddress address = new InetSocketAddress("www.google.com", 80);

     try
     {
        sock.connect(address, 3000);
        if(sock.isConnected()) status = true;
     }
     catch(Exception e)
     {
         status = false;       
     }
     finally
     {
        try
         {
            sock.close();
         }
         catch(Exception e){}
     }

     return status;
}
public boolean checkInternetConnection()
{
     boolean status = false;
     Socket sock = new Socket();
     InetSocketAddress address = new InetSocketAddress("www.google.com", 80);

     try
     {
        sock.connect(address, 3000);
        if(sock.isConnected()) status = true;
     }
     catch(Exception e)
     {
         status = false;       
     }
     finally
     {
        try
         {
            sock.close();
         }
         catch(Exception e){}
     }

     return status;
}
错爱 2024-08-11 11:47:32

(现在)有用于此目的的 API,但它们是特定于平台的:

(我会使用可用的特定工具)

There are (nowadays) APIs for this, but they are platform specific:

(I'd use the specific tools where available)

牵强ㄟ 2024-08-11 11:47:32

你可以简单地这样写

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Main {

    private static final String HOST = "localhost";

    public static void main(String[] args) throws UnknownHostException {

        boolean isConnected = !HOST.equals(InetAddress.getLocalHost().getHostAddress().toString());

        if (isConnected) System.out.println("Connected");
        else System.out.println("Not connected");

    }
}

You can simply write like this

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Main {

    private static final String HOST = "localhost";

    public static void main(String[] args) throws UnknownHostException {

        boolean isConnected = !HOST.equals(InetAddress.getLocalHost().getHostAddress().toString());

        if (isConnected) System.out.println("Connected");
        else System.out.println("Not connected");

    }
}
怪异←思 2024-08-11 11:47:32

这对我来说效果很好。

try{  
        InetAddress addr = InetAddress.getByName("google.com" );
        
    }catch(IOException e){
        JOptionPane.showMessageDialog(new JFrame(),"No Internet connection.\nTry again later", "Network Error", JOptionPane.ERROR_MESSAGE);    
    }

This have worked well for me.

try{  
        InetAddress addr = InetAddress.getByName("google.com" );
        
    }catch(IOException e){
        JOptionPane.showMessageDialog(new JFrame(),"No Internet connection.\nTry again later", "Network Error", JOptionPane.ERROR_MESSAGE);    
    }
千寻… 2024-08-11 11:47:32

还有一个 gradle 选项 --offline 这可能会导致您想要的行为。

There is also a gradle option --offline which maybe results in the behavior you want.

眼泪都笑了 2024-08-11 11:47:32

下面的代码可以让我们获取Android设备上的网络状态

public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView mtv=findViewById(R.id.textv);
            ConnectivityManager connectivityManager=
                  (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(((Network)connectivityManager.getActiveNetwork())!=null)
                    mtv.setText("true");
                else
                    mtv.setText("fasle");
            }
        }
    }

The following piece of code allows us to get the status of the network on our Android device

public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            TextView mtv=findViewById(R.id.textv);
            ConnectivityManager connectivityManager=
                  (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if(((Network)connectivityManager.getActiveNetwork())!=null)
                    mtv.setText("true");
                else
                    mtv.setText("fasle");
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文