Lo que sucede, creo yo, es que estás definiendo las conexiones como bloqueantes. Al ser una conexión bloqueante, si tu código llama a la función recv o recvfrom el hilo se quedará congelado dentro de la función hasta que recibas algo.
Para solucionar esto tienes dos opciones:
* Hacer la aplicación multihilo y crear un hilo nuevo para cada cliente.
* Hacer las conexiones no bloqueantes.
Yo te voy a comentar brevemente la segunda solución, para la primera el hecho de trabajar con sockets es casi irrelevante.
Para definir una conexión como no bloqueante tienes que hacer uso de la función fcntl, cuyo prototipo aparece a continuación:
#include <fcntl.h>
int fcntl(int fd, int cmd, int arg );
El primer parámetro es el descriptor ( un socket, un archivo... lo que corresponda. En tu caso el socket ).
El segundo parámetro permite indicar el sentido de la operación, lectura o escritura.
El tercer parámetro se usa en la escritura y permite modificar ciertos parámetros del desriptor.
En nuestro caso concreto, queremos hacer una operación de escritura ( vamos, modificar el comportamiento del descriptor ) y lo que queremos modificar es el comportamiento bloqueante.
Esto se consigue con la siguiente línea:
if ( fcntl( socket, F_SETFL, O_NONBLOCK ) < 0 )
{
// error
}
Una vez configurado el socket, si intentas realizar una operación de lectura y no hay datos para leer, el hilo de ejecución no se quedará esperando datos, sino que saldrá de la función indicándote que no ha leído absolutamente nada.
Esta circunstancia la puedes controlar así:
int data_length = recv ( socket, buffer, LENGTH_BUFFER, 0 );
if ( data_length > 0 )
{
// Se han recibido datos
}
else if ( data_length == 0 )
{
// No hay datos pendientes
}
else if ( data_length == SOCKET_ERROR )
{
// Error
}