paulo1205
(usa Ubuntu)
Enviado em 15/03/2019 - 09:14h
Essas aplicações mal-escritas são mesmo uma praga. Qual problema você está tendo?
Sockets TCP em estado
CLOSE_WAIT (de comunicações que já acabaram, mas o cara simplesmente esqueceu de chamar
close())?
Sockets TCP em estado
ESTABLISHED e com fila de recepção cheia e janela de recepção zerada, como se a aplicação tivesse esquecido que tem de consumir esses dados?
Sockets UDP abertos a fim de fazer alguma consulta, que já tiveram pacotes enviados que podem ter sido perdidos, mas a aplicação nem retenta a consulta nem desiste de esperar por uma resposta que seguramente nunca virá?
Em qualquer um desses casos, o único jeito de se livrar desses
sockets de modo limpo é, sim, corrigindo a aplicação. A segunda opção menos intrusiva é mesmo matar a instância em execução e a reiniciá-la.
Se você estiver disposto a experimentar — ou se gostar de viver perigosamente —, pode tentar interferir na execução da aplicação ativa através de uns truques de baixo nível, usando um depurador. Eu não conheço muito de Java, a ponto de saber se o Java Console ou algo semelhante poderia ser usado para injetar chamadas a métodos de fechamento de conexões, depois de identificar quais objetos detêm tais conexões. Mas com um depurador de baixo nível, como o
gdb, pode ser que você consiga assumir o controle do processo (e.g. com “gdb -p
pid_do_processo”) e então consiga injetar chamadas a
close() (e.g. dentro do
gdb, você poderia executar “
call close()”), forçando o fechamento do
socket em nível de processo do sistema operacional, não mais no nível de aplicação.
Dependendo de como a aplicação tenha sido programada e da frequência com que aconteçam as comunicações pela rede, pode ser que a operação acima seja relativamente indolor (o melhor cenário seria com tratadores de exceções nos lugares corretos e uma baixa frequência de comunicação, de modo que todo o processo de limpeza ocorra antes da próxima tentativa de comunicação; contudo se a aplicação tivesse sido bem programada, você não estaria tendo de fazer limpeza nenhuma). Mas não seria de espantar que uma forçação de fechamento do
socket criasse um fluxo de execução inesperado para a aplicação. Outra possível consequência seria chegar uma conexão nova que acabe reaproveitando o número de descritor do
socket você tiver fechado, e, ao mesmo tempo, a aplicação resolver reacordar o objeto que detém informações sobre o
socket antigo, o que implicaria que haveria dois objetos diferentes controlando o mesmo recurso (o número do descritor do arquivo), com a possibilidade de um objeto interferir com o outro.
... “Principium sapientiae timor Domini, et scientia sanctorum prudentia.” (Proverbia 9:10)