2010-06-06 13 views
5

Necesito escribir un servidor que acepte conexiones desde varias máquinas cliente, mantenga un registro de clientes conectados y envíe datos de clientes individuales según sea necesario. A veces, todos los clientes pueden ser contactados a la vez con el mismo mensaje, otras veces, puede ser un cliente individual o un grupo de clientes.Conexiones de socket múltiple

Como necesito confirmación de que los clientes recibieron la información y no quiero construir una estructura ACK para una conexión UDP, decidí usar un método de transmisión TCP. Sin embargo, he estado luchando por comprender cómo mantener conexiones múltiples y mantenerlas inactivas.

Parece que tengo tres opciones. Use un tenedor para cada conexión entrante para crear un proceso hijo por separado, use pthread_create para crear un hilo nuevo completo para cada proceso, o use select() para esperar en todos los ID de socket abiertos para una conexión.

Recomendaciones sobre cómo atacar esto? Empecé a trabajar con pthreads, pero dado que el rendimiento probablemente no sea un problema, el procesamiento multinúcleo no es necesario y tal vez haya una manera más sencilla.

+0

Como nota, estoy trabajando en C/C++ – BSchlinker

+0

También debo mencionar que el número de conexiones a este sistema es estático. Esta no es una máquina pública (las conexiones no cambiarán con el tiempo, es decir, no veo problemas de rendimiento como un problema). – BSchlinker

+1

Personalmente, multiplexaría usando select(), o preferiblemente kqueue() si se ejecuta en mac o bsd. Sin embargo, cualquiera de las tres opciones funcionaría, y las opciones pthread/fork son súper fáciles de implementar si su servidor va a tener un bajo conteo de clientes y una baja contención de clientes activos. –

Respuesta

5

Los procesos secundarios no son buenos, porque solo mueves el poste. Tendrá que hacer que los procesos de su hijo se comuniquen entre sí, luego volverá al mismo problema.

Es posible utilizar subprocesos, pero tendrá otros problemas si sus subprocesos siguen bloqueando la recepción de socket.

select() (o encuesta() en los nuevos (POSIX) Unixes) sigue siendo la mejor solución. Le dice a select() o poll() qué sockets o descriptores desea monitorear para los eventos (probablemente solo los eventos de entrada (lectura) son suficientes para usted), luego realiza la lectura solo en ese socket o descriptor que fue marcado por seleccionar()/encuesta(). Se garantiza que recv() no bloqueará.

4

Lea la página C10K para ver un montón de opciones. Luego lea el artículo High Performance Server Architecture. Estos responderán muchas preguntas para ti.

Iría con la tercera opción. Para esa mirada en epoll(4) y/o kqueue(2) instalaciones para el moderno rendimiento select/poll reemplazos.

+0

+1 para epoll(). También puede consultar boost :: asio, que eliminará gran parte del trabajo. – Thanatos

+1

Sí, 'boost :: asio' es una de las opciones para C++. Se menciona en las páginas que he vinculado. –

Cuestiones relacionadas