답변:
사용 된 포트가 마음에 들지 않으면 ServerSocket 생성자에 포트 0을 지정하면 사용 가능한 포트에서 수신 대기합니다.
ServerSocket s = new ServerSocket(0);
System.out.println("listening on port: " + s.getLocalPort());
특정 포트 세트를 사용하려면 가장 쉬운 방법은 작동 할 때까지 해당 포트를 반복하는 것입니다. 이 같은:
public ServerSocket create(int[] ports) throws IOException {
for (int port : ports) {
try {
return new ServerSocket(port);
} catch (IOException ex) {
continue; // try next port
}
}
// if the program gets here, no port in the range was found
throw new IOException("no free port found");
}
다음과 같이 사용할 수 있습니다.
try {
ServerSocket s = create(new int[] { 3843, 4584, 4843 });
System.out.println("listening on port: " + s.getLocalPort());
} catch (IOException ex) {
System.err.println("no available ports");
}
ssh -D 127.0.0.0:0 ...
? 아니요!). 정말 실망 스럽습니다. 우리가 사용할 수 있도록 많은 라이브러리 / 프로그램을 패치해야했습니다.
new ServerSocket(0)
이 점에서 다르지 않습니다. 이것에 대한 첫 번째 링크에는 아무것도 없습니다. 두 번째 링크는 실습이 좋지 않습니다. 일단 구성한 후에 ServerSocket
는 사용 하지 말고 닫지 말고 동일한 포트 번호를 재사용하십시오. 이 모든 것은 시간 낭비이며 타이밍 창 문제에 취약합니다.
ServerSocket의 생성자에 포트 번호로 0을 전달하면 포트가 할당됩니다.
Java 1.7부터 다음과 같은 try-with-resources를 사용할 수 있습니다.
private Integer findRandomOpenPortOnAllLocalInterfaces() throws IOException {
try (
ServerSocket socket = new ServerSocket(0);
) {
return socket.getLocalPort();
}
}
특정 인터페이스에서 열린 포트를 찾아야하는 경우 대체 생성자에 대해서는 ServerSocket 설명서를 확인하십시오 .
경고 : 이 방법으로 반환 된 포트 번호를 사용하는 코드는 경쟁 조건에 따라 달라질 수 있습니다. ServerSocket 인스턴스를 닫은 직후 다른 프로세스 / 스레드가 동일한 포트에 바인딩 될 수 있습니다.
SO_REUSEADDR
. 그리고 경쟁 조건이 있지만 그것을 고치기는 어렵습니다.
ServerSocket
포트 번호를 사용하여 다른 포트 를 열려고하면 작동하지 않을 수 있습니다. ServerSocket
닫는 대신 실제 를 반환하지 않는 이유는 여전히 미스터리입니다.
ServerSocket
대신에 대신 타사 코드를 수락하도록 변경할 수 없습니다 int
.
Wikipedia 에 따르면 '잘 알려진'포트가 필요하지 않은 경우 포트 49152
를 65535
사용해야합니다.
AFAIK 포트 사용 여부를 확인하는 유일한 방법은 포트를 열려고 시도하는 것입니다.
범위 내 에서 필요한 경우 :
public int nextFreePort(int from, int to) {
int port = randPort(from, to);
while (true) {
if (isLocalPortFree(port)) {
return port;
} else {
port = ThreadLocalRandom.current().nextInt(from, to);
}
}
}
private boolean isLocalPortFree(int port) {
try {
new ServerSocket(port).close();
return true;
} catch (IOException e) {
return false;
}
}
ServerSockets
성공 사례에서 두 개 를 만들 필요 가 없으며이 코드의 타이밍 창 문제로 고통받지 않습니다.
Spring을 사용하는 경우 http://docs.spring.io/spring/docs/4.0.5.RELEASE/javadoc-api/org/springframework/util/SocketUtils.html#findAvailableTcpPort--를 사용해보십시오.
SpringUtils.findAvailableTcpPort()
다른 답변에서 권장하는 것과 똑같은 방식으로 포트를 선택한 다음 시도하십시오 new ServerSocket(port)
.
http://java.sun.com/j2se/1.4.2/docs/api/java/net/ServerSocket.html#ServerSocket%28int%29를 참조하십시오.
지정된 포트에 바인드 된 서버 소켓을 작성합니다. 포트 0은 사용 가능한 포트에 소켓을 만듭니다.
서버가 시작되면 해당 소켓이 사용되지 않은 것입니다.
편집하다
다음과 같은 것 :
ServerSocket s = null ;
try {
s = new ServerSocket( 0 );
} catch( IOException ioe ){
for( int i = START; i < END ; i++ ) try {
s = new ServerSocket( i );
} catch( IOException ioe ){}
}
// At this point if s is null we are helpless
if( s == null ) {
throw new IOException(
Strings.format("Unable to open server in port range(%d-%d)",START,END));
}
new ServerSocket(0)
대안이 효과가 없다면 이것입니다. 내 제안을 사용할 가능성의 85 %가 있다고 생각합니다.
ServerSockets
되며 성공한 마지막 코드 만 유지합니다 . break
진술 이 필요합니다 .
를 사용하여 자체 서버를 만들려면 사용 ServerSocket
가능한 포트를 선택하십시오.
ServerSocket serverSocket = new ServerSocket(0);
int port = serverSocket.getLocalPort();
다른 서버 구현은 일반적으로 유사한 지원을 갖습니다. 예를 들어 Jetty 는 명시 적으로 설정하지 않으면 사용 가능한 포트를 선택합니다.
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
// don't call: connector.setPort(port);
server.addConnector(connector);
server.start();
int port = connector.getLocalPort();
그것은 당신에게별로 도움이되지는 않지만 내 (우분투) 컴퓨터에는 적어도 일부 앱에서 사용 / 예약 된 포트가 제공되는 / etc / services 파일이 있습니다. 이러한 앱의 표준 포트입니다.
이러한 응용 프로그램이 실행 중임을 보장하지는 않으며, 이러한 앱이 사용하는 기본 포트만 가능하므로 가능하면 사용하지 않아야합니다.
UDP의 절반과 TCP의 절반 인 500 개가 넘는 포트가 정의되어 있습니다.
파일은 IANA의 정보를 사용하여 작성됩니다 ( IANA 할당 포트 번호 참조) .
Spring을 사용하는 경우 Michail Nikolaev 가 제공하는 답변 이 가장 간단하고 깨끗하며 IMO를 상향 조정해야합니다. 편의상 Springframwework SocketUtils .findAvailableTcpPort () 메소드 를 사용하여 인라인 예제를 추가 하겠습니다 .
int randomAvailablePort = SocketUtils.findAvailableTcpPort();
한 줄만 있으면 쉽습니다. :). 물론 Utils 클래스는 다른 많은 흥미로운 방법을 제공합니다. 문서를 살펴 보는 것이 좋습니다.
'ServerSocket'클래스를 사용하면 주어진 포트가 사용 중인지 또는 사용 가능한지 식별 할 수 있습니다. ServerSocket은 정수 (포트 번호)를 인수로 사용하여 포트에서 서버 소켓을 초기화하는 생성자를 제공합니다. ServerSocket에서 IO 예외가 발생하면이 포트가 이미 사용중인 것으로 가정 할 수 있습니다.
다음 스 니펫은 사용 가능한 모든 포트를 가져 오는 데 사용됩니다.
for (int port = 1; port < 65535; port++) {
try {
ServerSocket socket = new ServerSocket(port);
socket.close();
availablePorts.add(port);
} catch (IOException e) {
}
}
참조 링크 .