Soquetes: descubra a disponibilidade da porta usando Java
Como determino programaticamente a disponibilidade de uma porta em uma determinada máquina usando Java?
ou seja, dado um número de porta, determine se ele já está sendo usado ou não ?.
— user54075
Embora esta pergunta é sobre como saber se uma determinada porta já está em uso, você pode ter desembarcado aqui tentando encontrar uma maneira de obter um número de porta livre, que stackoverflow.com/questions/2675362/... (com link para a minha essência .github.com / 3429822 ) cobre melhor.
Para qual propósito? Se você quiser apenas encontrar um soquete vazio para escutar, especifique zero. Qualquer técnica de exploração é susceptível de problemas-janela de tempo:. A porta pode ser vago quando você digitalizar e ocupada quando você vai a reivindicação em
Esta é a implementação proveniente do projeto Apache camel :
Eles também estão verificando o DatagramSocket para verificar se a porta está disponível em UDP e TCP.
— David Santamaria
Uma boa variante disso, se você tiver MINA, é AvailablePortFinder.getNextAvailable (1024), que fornece a próxima porta sem privilégios.
Isso não pega tudo no entanto. Fui mordido por um nginx em execução no TCP 8000, enquanto a rotina acima informa 8000 como disponível. Não faço ideia do porquê - suspeito que o nginx faz algumas coisas sorrateiras (isso é no OS X). A solução para mim é fazer o acima e também abrir um novo soquete ("localhost", porta) e retornar false se não houver uma exceção. Pensamentos?
Mesmo problema no Windows, tentando detectar se o servidor SMTP papercut está em execução. Uma solução em que você abre uma conexão a uma porta, em vez de tentar vinculá-la (como sugerido pelo comentário da Partly Clodys e pela resposta de Ivan) parece funcionar mais confiável.
Interessante. A chamada para setReuseAddress () é completamente inútil após o soquete já estar vinculado e também completamente contrária à finalidade do código.
Este código está sujeito a problemas na janela de temporização. Se o objetivo é criar uma ServerSocketescuta para alguma porta, é isso que ela deve fazer e retornar a ServerSocket. Criá-lo e, em seguida, fechá-lo e devolvê-lo não garante que um subseqüente ServerSocketpossa ser criado usando essa porta. O mesmo vale para DatagramSocket.
No Java 7, você pode usar o try-with-resource para obter um código mais compacto:
— eivindw
Isso não testa se a porta está disponível. Ele testa se está no estado LISTEN, se o endereço IP está acessível etc.
Além disso, este teste é bem lento (quase um segundo por porta).
— JMax
ele não deve retornar false quando um IOException é capturado?
— Baroudi Safwen 6/08/19
@BaroudiSafwen Depende inteiramente de qual é realmente a exceção. Pois ConnectException: 'connection refused', sim, ele deve retornar falso. Para tempos limite, nada que pudesse retornar seria válido, pois a resposta real não é conhecida. É por isso que essa técnica é inútil para esse fim.
Parece que a partir do Java 7, a resposta de David Santamaria não funciona mais de maneira confiável. Parece que você ainda pode usar um soquete de maneira confiável para testar a conexão.
— TwentyMiles
Quero verificar se um servidor proxy está disponível para fazer chamadas em seu nome.
— Dejell 01/01
A resposta de @ DavidSantamaria nunca funcionou. Nada a ver com o Java 7.
Se você não está muito preocupado com o desempenho, sempre pode tentar ouvir uma porta usando a classe ServerSocket . Se ele lança uma exceção, as probabilidades estão sendo usadas.
public static boolean isAvailable(int portNr) {
boolean portFree;
try (var ignored = new ServerSocket(portNr)) {
portFree = true;
portFree = false;
return portFree;
EDIT: Se tudo o que você está tentando fazer é selecionar uma porta gratuita, new ServerSocket(0)ela encontrará uma para você.
Use finalmente para limpeza (tente {...} pegar {...} finalmente {if (socket! = Null) socket.close ();} #
Você também pode definir "portTaken = (socket == null);" no final, em vez de fazê-lo na captura.
— Hosam Aly 12/01/2009
Não senti que isso se enquadrasse no escopo pretendido da pergunta do autor.
Existe uma maneira de fazer isso sem tentar / pegar? Eu não me importaria de usar nenhuma porta disponível para meus propósitos, mas iterar sobre os números de porta e tentar capturar cada uma delas até encontrar uma gratuita é um pouco inútil. Não existe um método 'nativo booleano disponível (int)' em algum lugar, que apenas verifica?
— Oren Shalev
O novo SeverSocket (0) selecionará automaticamente uma porta livre.
A solução a seguir é inspirada na implementação do Spring-core do SocketUtils (licença Apache).
Comparado a outras soluções Socket(...), é bastante rápido (testando 1000 portas TCP em menos de um segundo):
As soluções baseadas em soquete try / catch podem não gerar resultados precisos (o endereço do soquete é "localhost" e, em alguns casos, a porta pode ser "ocupada" não pela interface de loopback e, pelo menos no Windows, vi esse teste falhar, ou seja o prot falsamente declarado como disponível).
Há uma biblioteca legal chamada SIGAR , o seguinte código pode conectá-lo:
— Shmil The Cat
Recebo: "no sigar-x86-winnt.dll em java.library.path" Infelizmente, é necessário o download de alguma dll adicional que não é realmente viável no ambiente corporativo (não tenho controle sobre o sistema de CI). Tão ruim .... Obrigado de qualquer maneira.
— Uthomas 18/04
@uthomas Eu acho que você ainda tem controle sobre o pacote de implantação de aplicativos, se esse for o caso, você sempre pode fornecer DLL / SOs de tempo de execução nativo Sigar perto dos seus JARs e definir o caminho da lib JAVA de forma pragmática aplicativo lançado pela JVM).
Uma limpeza da resposta apontada por David Santamaria:
Isso ainda está sujeita a uma condição de corrida apontado por user207421 nos comentários a resposta de David Santamaria (algo poderia pegar o porto após esse método fecha o ServerSockete DatagramSockete volta).
No meu caso, ajudou a tentar conectar-se à porta - se o serviço já estiver presente, ele responderia.