Estás haciendo una pregunta equivocada aquí. Realmente no es posible simplemente "cerrar un puerto" desde fuera de la aplicación que abrió el socket escuchando en él. La única forma de hacerlo es eliminar por completo el proceso que posee el puerto. Luego, en aproximadamente un minuto o dos, el puerto volverá a estar disponible para su uso. Esto es lo que está sucediendo (si no te importa, salta al final donde te muestro cómo matar el proceso que posee un puerto en particular):
Los puertos son recursos asignados por el sistema operativo a diferentes procesos. Esto es similar a pedirle al sistema operativo un puntero de archivo. Sin embargo, a diferencia de los punteros de archivo, solo UN proceso a la vez puede tener un puerto. A través de la interfaz de socket BSD, los procesos pueden hacer una solicitud para escuchar en un puerto, que luego el sistema operativo otorgará. El sistema operativo también se asegurará de que ningún otro proceso tenga el mismo puerto. En cualquier momento, el proceso puede liberar el puerto cerrando el socket. El sistema operativo reclamará el puerto. Alternativamente, si el proceso finaliza sin liberar el puerto, el sistema operativo finalmente recuperará el puerto (aunque no sucederá de inmediato: tomará unos minutos).
Ahora, lo que desea hacer (simplemente cierre el puerto desde la línea de comandos), no es posible por dos razones. Primero, si fuera posible, significaría que un proceso simplemente podría robar el recurso de otro proceso (el puerto). Esta sería una mala política, a menos que esté restringida a procesos privilegiados. La segunda razón es que no está claro qué pasaría con el proceso que poseía el puerto si dejamos que continúe ejecutándose. El código del proceso se escribe asumiendo que posee este recurso. Si simplemente lo quitáramos, terminaría fallando por sí mismo, por lo que los sistemas operativos no le permiten hacer esto, incluso si es un proceso privilegiado. En cambio, simplemente debes matarlos.
De todos modos, aquí se explica cómo matar un proceso que posee un puerto en particular:
sudo netstat -ap | grep :<port_number>
Eso generará la línea correspondiente al puerto de retención del proceso, por ejemplo:
tcp 0 0 *:8000 *:* LISTEN 4683/procHoldingPort
En este caso, procHoldingPort es el nombre del proceso que abrió el puerto, 4683 es su pid y 8000 (tenga en cuenta que es TCP) es el número de puerto que posee.
Luego, mira en la última columna, verás /. Entonces ejecute esto:
kill <pid>
Si eso no funciona (puede verificarlo volviendo a ejecutar el comando netstat). Hacer esto:
kill -9 <pid>
En general, es mejor evitar enviar SIGKILL si puedes. Por eso te digo que lo intentes kill
antes kill -9
. Solo usando kill
envía la SIGTERM más suave.
Como dije, aún se necesitarán unos minutos para que el puerto se vuelva a abrir si haces esto. No sé una manera de acelerar esto. Si alguien más lo hace, me encantaría escucharlo.