Bagaimana cara saya secara terprogram menentukan ketersediaan port di mesin tertentu yang menggunakan Java?
yaitu diberi nomor port, tentukan apakah sudah digunakan atau belum ?.
Bagaimana cara saya secara terprogram menentukan ketersediaan port di mesin tertentu yang menggunakan Java?
yaitu diberi nomor port, tentukan apakah sudah digunakan atau belum ?.
Jawaban:
Ini adalah implementasi yang berasal dari proyek unta Apache :
/**
* Checks to see if a specific port is available.
*
* @param port the port to check for availability
*/
public static boolean available(int port) {
if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
throw new IllegalArgumentException("Invalid start port: " + port);
}
ServerSocket ss = null;
DatagramSocket ds = null;
try {
ss = new ServerSocket(port);
ss.setReuseAddress(true);
ds = new DatagramSocket(port);
ds.setReuseAddress(true);
return true;
} catch (IOException e) {
} finally {
if (ds != null) {
ds.close();
}
if (ss != null) {
try {
ss.close();
} catch (IOException e) {
/* should not be thrown */
}
}
}
return false;
}
Mereka juga memeriksa DatagramSocket untuk memeriksa apakah port tersedia di UDP dan TCP.
Semoga ini membantu.
ServerSocket
port listening ke beberapa, itulah yang harus dilakukan, dan mengembalikan ServerSocket
. Membuatnya dan kemudian menutupnya dan mengembalikannya memberikan jaminan nol bahwa berikutnya ServerSocket
dapat dibuat menggunakan port itu. Ditto for DatagramSocket
.
Untuk Java 7 Anda dapat menggunakan try-with-resource untuk kode yang lebih ringkas:
private static boolean available(int port) {
try (Socket ignored = new Socket("localhost", port)) {
return false;
} catch (IOException ignored) {
return true;
}
}
ConnectException: 'connection refused'
, ya itu harus mengembalikan salah. Untuk waktu tunggu, tidak ada yang bisa dikembalikan yang valid, karena jawaban sebenarnya tidak diketahui. Itulah mengapa teknik ini tidak berguna untuk tujuan ini.
Tampaknya mulai Java 7, jawaban David Santamaria tidak berfungsi lagi. Namun, sepertinya Anda masih dapat menggunakan Socket untuk menguji koneksi.
private static boolean available(int port) {
System.out.println("--------------Testing port " + port);
Socket s = null;
try {
s = new Socket("localhost", port);
// If the code makes it this far without an exception it means
// something is using the port and has responded.
System.out.println("--------------Port " + port + " is not available");
return false;
} catch (IOException e) {
System.out.println("--------------Port " + port + " is available");
return true;
} finally {
if( s != null){
try {
s.close();
} catch (IOException e) {
throw new RuntimeException("You should handle this error." , e);
}
}
}
}
Jika Anda tidak terlalu peduli dengan kinerja, Anda selalu dapat mencoba mendengarkan di port menggunakan kelas ServerSocket . Jika itu melempar pengecualian kemungkinan itu sedang digunakan.
public static boolean isAvailable(int portNr) {
boolean portFree;
try (var ignored = new ServerSocket(portNr)) {
portFree = true;
} catch (IOException e) {
portFree = false;
}
return portFree;
}
EDIT: Jika semua yang Anda coba lakukan adalah memilih port gratis, maka new ServerSocket(0)
akan menemukan satu untuk Anda.
Solusi berikut ini terinspirasi oleh implementasi SocketUtils dari Spring-core (lisensi Apache).
Dibandingkan dengan solusi lain yang menggunakannya Socket(...)
cukup cepat (menguji 1000 port TCP dalam waktu kurang dari satu detik):
public static boolean isTcpPortAvailable(int port) {
try (ServerSocket serverSocket = new ServerSocket()) {
// setReuseAddress(false) is required only on OSX,
// otherwise the code will not work correctly on that platform
serverSocket.setReuseAddress(false);
serverSocket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), port), 1);
return true;
} catch (Exception ex) {
return false;
}
}
Solusi berbasis soket coba / tangkap, mungkin tidak memberikan hasil yang akurat (alamat soket adalah "localhost" dan dalam beberapa kasus port dapat "ditempati" bukan oleh antarmuka loopback dan setidaknya pada Windows saya telah melihat tes ini gagal yaitu prot secara salah dinyatakan sebagai tersedia).
Ada perpustakaan keren bernama SIGAR , kode berikut dapat menghubungkan Anda:
Sigar sigar = new Sigar();
int flags = NetFlags.CONN_TCP | NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT; NetConnection[] netConnectionList = sigar.getNetConnectionList(flags);
for (NetConnection netConnection : netConnectionList) {
if ( netConnection.getLocalPort() == port )
return false;
}
return true;
Pembersihan dari jawaban yang ditunjukkan oleh David Santamaria:
/**
* Check to see if a port is available.
*
* @param port
* the port to check for availability.
*/
public static boolean isPortAvailable(int port) {
try (var ss = new ServerSocket(port); var ds = new DatagramSocket(port)) {
return true;
} catch (IOException e) {
return false;
}
}
Ini masih tunduk pada kondisi balapan yang ditunjukkan oleh pengguna207421 di komentar untuk jawaban David Santamaria (sesuatu bisa mengambil port setelah metode ini menutup ServerSocket
dan DatagramSocket
dan kembali).
Dalam kasus saya, ini membantu untuk mencoba dan menyambung ke port - jika layanan sudah ada, itu akan merespons.
try {
log.debug("{}: Checking if port open by trying to connect as a client", portNumber);
Socket sock = new Socket("localhost", portNumber);
sock.close();
log.debug("{}: Someone responding on port - seems not open", portNumber);
return false;
} catch (Exception e) {
if (e.getMessage().contains("refused")) {
return true;
}
log.error("Troubles checking if port is open", e);
throw new RuntimeException(e);
}
Dalam kasus saya, saya harus menggunakan kelas DatagramSocket.
boolean isPortOccupied(int port) {
DatagramSocket sock = null;
try {
sock = new DatagramSocket(port);
sock.close();
return false;
} catch (BindException ignored) {
return true;
} catch (SocketException ex) {
System.out.println(ex);
return true;
}
}
Jangan lupa import dulu
import java.net.DatagramSocket;
import java.net.BindException;
import java.net.SocketException;
Saya telah mencoba sesuatu seperti ini dan bekerja sangat baik dengan saya
Socket Skt;
String host = "localhost";
int i = 8983; // port no.
try {
System.out.println("Looking for "+ i);
Skt = new Socket(host, i);
System.out.println("There is a Server on port "
+ i + " of " + host);
}
catch (UnknownHostException e) {
System.out.println("Exception occured"+ e);
}
catch (IOException e) {
System.out.println("port is not used");
}