ver sierra saber puertos puerto mac listado high como alternativos abrir abiertos macos sockets osx-elcapitan

macos - sierra - puertos http alternativos



Libere el puerto UDP utilizado por el proceso inactivo en OS X (5)

Estoy en OS X 10.11.6 y trato de ejecutar un programa que normalmente escucha en el puerto UDP 8008 al inicio.

Este programa normalmente también genera un par de procesos hijos auxiliares durante su operación, pero el puerto está vinculado por el proceso padre.

Lamentablemente, al salir del programa, a veces el puerto permanece abierto, aunque el programa (padre + hijos) ya no exista.

Cuando esto sucede, si trato de ejecutar el programa nuevamente, naturalmente falla con un error EADDRINUSE , y en estos casos, sin importar lo que intento, la única solución que encontré fue reiniciar el equipo.

Me está costando creer que no puedo liberar el puerto sin reiniciar.

Aquí hay algunos diagnósticos que ejecuté hasta ahora (ejecuté todos estos con y sin sudo ):

Encuentre el proceso usando el puerto 8008 con lsof :

$ lsof -i -n -P | grep UDP | grep 8008

Pero sorprendentemente no devuelve ningún resultado.

Sin embargo, tuve más suerte con netstat :

$ netstat -tulnvp udp | grep 8008 udp4 0 0 *.8008 *.* 196724 9216 47205 0

Entonces, el puerto está realmente atado, y el culpable es pid 47205 , sin embargo:

$ ps aux | grep 47205

No devuelve nada Lo mismo para los PID 47206 y 47207 (sin duda los PID asignados a los niños). También probé otras variaciones del grep (nombre del programa, ruta, etc.).

También busqué cualquier proceso que informe 47205 como su padre:

$ ps -axo pid,ppid,command | grep 47205

Entonces los procesos de los niños también están claramente muertos.

Al no poder kill nada, intenté lanzar SIGHUP con la esperanza de que pudiera eliminar cualquier proceso hijo zombie:

$ sudo kill HUP 1 $ sudo kill -s HUP 1

Pero, por desgracia, netstat todavía muestra el límite del puerto.

Por último, traté de reiniciar la interfaz de loopback:

$ sudo ifconfig lo down $ sudo ifconfig lo up

Pero de nuevo, sin ningún efecto.

He esperado varias horas desde la última vez que se ejecutó el programa, así que estoy bastante seguro de que ya habría pasado el tiempo de espera, pero el puerto no será liberado.

¿Alguna idea sobre cómo forzar la liberación del puerto sin un reinicio?

Editar:

  • El programa en cuestión es Patchwork envuelto en electrones.
  • Esta pregunta proviene de este problema de Github .
  • Aunque encontrar una solución / corrección de errores que evite que el problema ocurra en primer lugar sería ideal, también estoy interesado en formas de cerrar manualmente ese puerto desde la terminal

De hecho, es posible cerrar el puerto manualmente sin reiniciar la máquina. En varios sabores de Linux esto generalmente se hace con w / GDB emitiendo syscalls enmascarados como un proceso (por ejemplo, close(fd) syscall en el descriptor de archivo sockets).

El proceso para eso:

  • Abra un puerto UDP: netcat -u 127.0.0.1 33333 .
  • Compruebe el puerto UDP: netstat -npu (u for UDP) , que le proporcionará el PID que ocupa ese puerto.
  • Ejecute: lsof -np $pid para que ese PID obtenga el descriptor de archivo para el socket.
  • Luego ejecute GDB para ese PID: sudo gdb -p 73599
  • Cuando dentro de GDB ejecuta call close(file_descriptor)

Ejemplo:

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME netcat 73599 ubunt cwd DIR 259,2 4096 13895497 /home/ubunt/Downloads netcat 73599 ubunt rtd DIR 259,2 4096 2 / netcat 73599 ubunt txt REG 259,2 31248 28835938 /bin/nc.openbsd netcat 73599 ubunt mem REG 259,2 47600 23990813 /lib/x86_64-linux-gnu/libnss_files-2.23.so netcat 73599 ubunt mem REG 259,2 1868984 23990714 /lib/x86_64-linux-gnu/libc-2.23.so netcat 73599 ubunt mem REG 259,2 101200 23990866 /lib/x86_64-linux-gnu/libresolv-2.23.so netcat 73599 ubunt mem REG 259,2 81040 23990710 /lib/x86_64-linux-gnu/libbsd.so.0.8.2 netcat 73599 ubunt mem REG 259,2 162632 23990686 /lib/x86_64-linux-gnu/ld-2.23.so netcat 73599 ubunt 0u CHR 136,19 0t0 22 /dev/pts/19 netcat 73599 ubunt 1u CHR 136,19 0t0 22 /dev/pts/19 netcat 73599 ubunt 2u CHR 136,19 0t0 22 /dev/pts/19 netcat 73599 ubunt 3u IPv4 22142418 0t0 UDP 127.0.0.1:45255->127.0.0.1:33333

Entonces GDB:

$sudo gdb -p 73599 ... (gdb) call close(3u) $1 = 0

Verás que el puerto ya no está allí:

ubunt@ubunt-MS-7A94:~$ lsof -np 73599 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME netcat 73599 ubunt cwd DIR 259,2 4096 13895497 /home/ubunt/Downloads netcat 73599 ubunt rtd DIR 259,2 4096 2 / netcat 73599 ubunt txt REG 259,2 31248 28835938 /bin/nc.openbsd netcat 73599 ubunt mem REG 259,2 47600 23990813 /lib/x86_64-linux-gnu/libnss_files-2.23.so netcat 73599 ubunt mem REG 259,2 1868984 23990714 /lib/x86_64-linux-gnu/libc-2.23.so netcat 73599 ubunt mem REG 259,2 101200 23990866 /lib/x86_64-linux-gnu/libresolv-2.23.so netcat 73599 ubunt mem REG 259,2 81040 23990710 /lib/x86_64-linux-gnu/libbsd.so.0.8.2 netcat 73599 ubunt mem REG 259,2 162632 23990686 /lib/x86_64-linux-gnu/ld-2.23.so netcat 73599 ubunt 0u CHR 136,19 0t0 22 /dev/pts/19 netcat 73599 ubunt 1u CHR 136,19 0t0 22 /dev/pts/19 netcat 73599 ubunt 2u CHR 136,19 0t0 22 /dev/pts/19

GDB está disponible para MacOS, por lo que también debería funcionar para su caso.


El sistema puede mantener el socket abierto hasta que el proceso de E / S esté en progreso. Incluso cuando el proceso murió pero no cerró explícitamente el socket. Si su zócalo no se cerró en horas, probablemente le falte algo. Intente utilizar la investigación de kernel de bajo nivel en lugar de utilidades de nivel superior como netstat o lsof.

Renuncia

No soy experto en OS X, y la mayoría de los comandos para Linux. Todavía lo dejo allí si alguien más tiene el mismo problema.

1. Trate de ver si el zócalo sigue vivo (opcional)

Puedo sugerir que revise la comunicación de socket.

tcpdump -A -s0 port 8080 and tcpdump -A -s0 -ilo port 8080

Si ve datos transferidos a través de un socket, puede estar seguro de que el proceso está activo. O puede ser uno de sus hijos. Más tarde puedes atrapar el pid con strace

2. Verifica el proceso y su estado

Linux tiene maravillosos procfs . Puedes obtener tantas cosas desde allí. Y seguro de que puedes ver todos los descriptores de archivos abiertos

ls -al /proc/47205/fd

Si ve la salida y / proc / 47205 existe el pid no liberado, sin embargo, ps aparece. Verá todos los archivos abiertos y su fds. Parece

133 -> socket: [32242509]

Donde 133 es un número fd

Lamentablemente, OS X no tiene el sistema de archivos / proc. El comando alternativo que encontré.

procexp 47205 fds

Pero no estoy seguro de que funcione al 100%.

3. Cerrar el descriptor de archivo (socket) en otro proceso

En linux hay un buen comando

fuser -k -n udp 8080

Esto cerrará explícitamente todos los procesos que bloquean el puerto. Parece que OS X también puede tener fusor

Otra forma real de hackers es conectarse para procesar con gdb y ejecutar comandos dentro del proceso, porque los números de los descriptores de archivos son válidos solo en el entorno del proceso, exactamente como @Mindaugas Bernatavičius escribió:

gdb -p 47205 >call shutdown([fd_number],2) >call close([fd_number])

Hay una tercera forma , cuando sea posible, puede reiniciar toda la red. Nota Plese, abajo y arriba solo la interfaz loopback no es suficiente. En la ejecución de Linux

systemctl restart network

4. Qué hacer para evitar que el socket se atasque en el sistema

Siempre debe asegurarse de que el calcetín esté cerrado antes de que salga su programa. He visto muchos problemas con nodejs que los sockets permanecen abiertos. Llamar a Socket.destroy () resolverá el problema

Puede poner su código de socket aquí, antes de salir de la aplicación:

app.on (''close'', función (código) {

// El usuario cerró la aplicación. Mata el proceso de host.

process.exit ();

});


En su código, después de crear el socket, pero antes de la llamada de bind , invoque lo siguiente:

int val = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));

Luego llama bind . Lo anterior permitirá que el enlace de socket tenga éxito incluso si el puerto está en uso.

Dos procesos, que intentan una recvfrom en el mismo puerto, darán como resultado uno de los procesos que reciben el paquete, pero no el otro. Y no es determinista cuál será. Así que asegúrese de no tener realmente dos procesos ejecutándose legítimamente y compartiendo el puerto.


Su pregunta es similar a:

Como dijiste:

Por último, traté de reiniciar la interfaz de loopback:

$ sudo ifconfig lo down

$ sudo ifconfig lo up

¿Intentó retener todas las interfaces de red disponibles (lan o wlan) y no solo el loopback?

En lugar de ifconfig también puede utilizar la utilidad de comando nativa de MacOS (desde here ) para apagar y luego encender el dispositivo (adapte en0 al your device name ):

networksetup -setairportpower en0 off networksetup -setairportpower en0 on

También puede intentar liberar y renovar DHCP con:

sudo dhclient -v -r

Saludos