Làm cách nào để lập trình xác định tính khả dụng của một cổng trong một máy nhất định bằng Java?
tức là đã cho một số cổng, xác định xem nó đã được sử dụng hay chưa?.
Làm cách nào để lập trình xác định tính khả dụng của một cổng trong một máy nhất định bằng Java?
tức là đã cho một số cổng, xác định xem nó đã được sử dụng hay chưa?.
Câu trả lời:
Đây là triển khai đến từ dự án lạc đà 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;
}
Họ cũng đang kiểm tra DatagramSocket để kiểm tra xem cổng có khả dụng trong UDP và TCP không.
Hi vọng điêu nay co ich.
ServerSocket
cổng nghe, thì đó là điều nên làm và trả lại ServerSocket
. Tạo nó và sau đó đóng nó và trả lại nó không đảm bảo rằng ServerSocket
có thể tạo ra một cái tiếp theo bằng cổng đó. Ditto cho DatagramSocket
.
Đối với Java 7, bạn có thể sử dụng try-with-resource cho mã nhỏ gọn hơn:
private static boolean available(int port) {
try (Socket ignored = new Socket("localhost", port)) {
return false;
} catch (IOException ignored) {
return true;
}
}
ConnectException: 'connection refused'
, có nó sẽ trả lại sai. Đối với thời gian chờ, không có gì nó có thể trả về sẽ hợp lệ, vì câu trả lời thực tế không được biết đến. Đó là lý do tại sao kỹ thuật này là vô dụng cho mục đích này.
Có vẻ như kể từ Java 7, câu trả lời của David Santamaria không còn hoạt động đáng tin cậy nữa. Tuy nhiên, có vẻ như bạn vẫn có thể sử dụng Ổ cắm một cách đáng tin cậy để kiểm tra kết nối.
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);
}
}
}
}
Nếu bạn không quá quan tâm đến hiệu suất, bạn luôn có thể thử nghe trên một cổng bằng lớp ServerSocket . Nếu nó ném một tỷ lệ cược ngoại lệ thì nó đang được sử dụng.
public static boolean isAvailable(int portNr) {
boolean portFree;
try (var ignored = new ServerSocket(portNr)) {
portFree = true;
} catch (IOException e) {
portFree = false;
}
return portFree;
}
EDIT: Nếu tất cả những gì bạn đang cố gắng làm là chọn một cổng miễn phí thì new ServerSocket(0)
sẽ tìm một cổng cho bạn.
Giải pháp sau đây được lấy cảm hứng từ việc triển khai Spring-core (giấy phép Apache) của SocketUtils .
So với các giải pháp khác sử dụng Socket(...)
nó khá nhanh (kiểm tra 1000 cổng TCP trong chưa đầy một giây):
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;
}
}
Các giải pháp dựa trên ổ cắm thử / bắt, có thể không mang lại kết quả chính xác (địa chỉ ổ cắm là "localhost" và trong một số trường hợp, cổng có thể bị "chiếm" không phải bởi giao diện loopback và ít nhất là trên Windows tôi đã thấy thử nghiệm này không thành công các tuyên bố giả mạo là có sẵn).
Có một thư viện thú vị tên là SIGAR , đoạn mã sau có thể nối bạn:
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;
Dọn dẹp câu trả lời được chỉ ra bởi 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;
}
}
Đây vẫn là đối tượng của một tình trạng chủng tộc đã chỉ ra bởi user207421 trong các ý kiến để trả lời David Santamaria của (một cái gì đó có thể lấy các cổng sau phương pháp này đóng ServerSocket
và DatagramSocket
và lợi nhuận).
Trong trường hợp của tôi, nó đã giúp thử và kết nối với cổng - nếu dịch vụ đã có sẵn, nó sẽ đáp ứng.
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);
}
Trong trường hợp của tôi, tôi đã phải sử dụng lớp 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;
}
}
Đừng quên nhập trước
import java.net.DatagramSocket;
import java.net.BindException;
import java.net.SocketException;
Tôi đã thử một cái gì đó như thế này và nó hoạt động rất tốt với tôi
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");
}