2012-09-10 18 views
7

Estoy ejecutando dos instancias de stunnel en Windows 7, configurado para escuchar el mismo puerto, y parece que ambos están escuchando con éxito en el mismo puerto (simplemente usando socket()/bind()/listen()). Ambos casos parecen tener éxito con todas las llamadas y se muestran en un netstat:¿Cómo están escuchando dos procesos en el mismo puerto en Windows 7?

C:\>netstat -ano | grep 8000 
    TCP 0.0.0.0:8000   0.0.0.0:0    LISTENING  5828 
    TCP 0.0.0.0:8000   0.0.0.0:0    LISTENING  5852 

El primero se pone a escuchar todas las peticiones entrantes.

Esto es bastante opuesto a todas mis expectativas. (Esperaba que EADDRINUSE me dijera que el puerto estaba ocupado). Entonces ....

  1. ¿Por qué/cómo funciona? ¿Este comportamiento es útil en algún contexto?
  2. No deseo que una instancia se ejecute correctamente si otra aplicación va a atrapar las solicitudes entrantes ... ¿Cómo hago que el puerto sea exclusivo?

Respuesta

7

Esto se puede lograr si el socket se abrió con el indicador SO_REUSEADDR, que no es poco común para las aplicaciones de socket TCP.

Típicamente, SO_REUSEADDR se utiliza para una de dos cosas:

  1. Cuando un proceso se ha estrellado, han sido sacrificadas, o por la fuerza reiniciado sin tener la oportunidad de cerrar sus zócalos. O el proceso salió pero el socket (o el socket de conexión hijo) todavía está en un estado FIN_WAIT o FIN_WAIT2. El segundo proceso puede abrir el socket sin obtener un código de error "ya en uso". He leído un par de publicaciones en S.O. sugiriendo que esta es una mejor práctica para sockets TCP.

  2. El mismo programa de servidor se bifurca o se ejecuta varias veces al mismo tiempo. Esto permite el equilibrio de carga sin el programa de servidor escrito para hacer uso de subprocesos. Normalmente, la "otra instancia" del programa que escucha en el socket aceptará las conexiones entrantes mientras que la primera está ocupada con otra conexión.

En cuanto a su segunda pregunta, lo más fácil es no utilizar SO_REUSEADDR. Si le preocupa que pueda haber una aplicación deshonesta que intente usar SO_REUSADDR, entonces su aplicación puede usar SO_EXCLUSIVEADDRUSE. (Una bandera, que básicamente dice: "no permita que otras aplicaciones abran este mismo puerto con SO_REUSEADDR.)

+0

Gracias, pensé que la bandera era idéntica a la bandera UNIX del mismo nombre. MSDN fue esclarecedor: http: //msdn.microsoft.com/en-us/library/windows/desktop/ms740621(v=vs.85).aspx – Olson

Cuestiones relacionadas