-->

Check if Port is open on Android/Java

2020-07-25 17:58发布

问题:

I would like to check if a port is open, or a server is running on it.
I already tried it in multiple ways, like with "/system/bin/ping" and "InetAdress", but if im right I cant ping a specified port with these :/

This time i made it with the idea DatagramSockets like so:

try { String messageStr="Hello!";
   int server_port = 25565;
   DatagramSocket s = new DatagramSocket();
   InetAddress local = InetAddress.getByName("11.11.11.11");
   int msg_length=messageStr.length();
   byte[] message = messageStr.getBytes();
   DatagramPacket p = new DatagramPacket(message, msg_length,local,server_port); 
   textView1.setText("Inet");
   s.send(p); 
   textView1.setText("Send");
} catch (Exception e) {}

I get the "Inet", but no "Send" message, so i get stuck at sending. I tried to get the exception message, and it is NetworkOnMainThreadException..

回答1:

You cannot ping a specific port. A "ping" is an ICMP echo request. ICMP is an internet layer protocol and as such has no concept of a "port".

You could use a Socket to attempt to establish a TCP connection to the port. If it connects, then something was listening for TCP connections. If it doesn't connect, then it was unreachable in some way.

You could use a DatagramSocket to attempt to send a packet to the port. If it succeeds, then something is probably receiving data. If it fails, then something definitely went wrong (incidentally, an ICMP error message is sent back if a UDP packet is received that is addressed to a port that is not open for UDP, or if something actively refuses the packet on the way).

You'd have to use both of the above to check both TCP and UDP.

Note that InetAddress uses an ICMP request as ping by default, but if it does not have permission to do that, it will fall back on attempting to establish a TCP connection instead. However, in the case that it does have permission to generate ICMP packets, there is no way to force it to attempt a TCP connection instead. So if you want to use that method, just use a Socket.



回答2:

You may try to parse the output of netstat command to check whether there is something listening on the desired port.

So use ProcessBuilder, netstat command and some parsing logic.



回答3:

public ServerSocket create_server_socket( InetAddress[] ips, int[] ports) throws IOException {

    for( InetAddress ip: ips ) {
        for (int port : ports) {
            try {
                return new ServerSocket(port,0,ip);
            } catch (IOException ex) {
                continue; // try next port
            }
        }
        //try next ip
     }

    // if the program gets here, no ip:port in the range was found
    throw new IOException("no free ip:port found");
}


回答4:

Instead of trying to find open port or server running, just let the server broadcast the service and listen for replies from clients, check this link: http://home.heeere.com/tech-androidjmdns.html Hope this helps.