2015-01-08 2 views
0

В архитектуре клиент-сервер у меня есть сервер, который принимает подключения от клиентов. я хочу, чтобы сервер принимал 3 одновременных соединения, а остальные соединения (когда они были доступны) были переведены на удержание для обслуживания в режиме FIFO. Каким будет правильный способ?Соединения сокетов очереди в C

Один из возможных подходов, что я думал это

Создание счетчика и проверка, если ее меньше, чем 3, принимать, обслуживать клиентов в новом потоке, и приращение счетчика. Когда счетчик больше 3, просто примите и сохраните дескриптор сокета в очереди. Когда клиент завершает свою работу, остановите поток (например, присоединившись) и счетчик декретов, чтобы разрешить другому клиенту. Если очередь не пуста, введите дескриптор сокета, создайте поток и выполните обслуживание клиента.

Ваш отзыв приветствуется.

+2

Или вы можете иметь 3 рабочих потока, каждый из которых запрашивает запросы на соединение из очереди. (В общем, прием соединения, а затем сохранение его на удержании может быть не лучшим опытом с точки зрения клиента.) – Inspired

+0

, поэтому вы имеете в виду, что я держу все соединения в очереди и имею 3 рабочих потока, которые продолжают появляться и обслуживать? , о, да, я согласен с вами в этом, но это просто для практики. –

+0

Исправить. Это просто упрощение схемы, которую вы предложили (не более создания/объединения потоков, а счетчик не нужен). – Inspired

ответ

0

С listen Функция имеет отставание, которое вы можете установить, т.е. он будет удерживать все соединения в очереди и когда вызывается accept, первый элемент, ожидающий в очереди, фактически принимается, решение из этого аспекта выглядит следующим образом.

В бесконечном цикле допускаются только соединения, если счетчик меньше определенного номера (максимальное количество клиентов, которые будут одновременно обслуживаться). Объявите mutex, который защищает счетчик, который увеличивается каждый раз, когда соединение принимается. Объявить переменную условия b, используемую для сигнализации, когда поток завершил свою задачу. Используя эту переменную условия и мьютекс, подождите, если счетчик больше X. Когда поток, обслуживающий клиента, выполняет свою задачу, счетчик декремента и сигнализирует условие. Следовательно, бесконечный цикл снова зациклится и примет уже включенный клиент.

Одним из возможных реализаций этого может быть:

// global variable 
pthread_mutex_t lock; 
pthread_cond_t cv; 
int number_of_connected_client = 0; 

// a function executed by a thread to handle each user 
void *client_thread(void *arg) { 

    /* some code */ 

    // thread is about to finish and return 
    // client disconnected --> decrement number of connected clients 
    // signal that a client disconnected 
    pthread_mutex_lock(&lock); 
    number_of_connected_client-- ; 
    pthread_cond_signal(&cv); 
    pthread_mutex_unlock(&lock); 
    return 0; 
} 

// infinte loop for accepting connections 
while (1) { 

    // serve 2 users at a time, queue the rest of the clients in the listen's queue 
    if(number_of_connected_client >= 2) { 
    pthread_mutex_lock(&lock);  
    pthread_cond_wait(&cv, &lock); 
    pthread_mutex_unlock(&lock); 
    } 

    connfd = accept(listenfd, (struct sockaddr *) NULL, NULL); 

    // create a thread and serve the client 
    if(pthread_create(&thread_id , NULL , client_thread, (void*)connfd) <0) 
    { 
    // error in creating thread 
    // do something 
    } 

    // client is served --> increment number of connected clients 
    else { 
    pthread_mutex_lock(&lock); 
    number_of_connected_client ++; 
    pthread_mutex_unlock(&lock); 
    } 

} 

Это только простое решение, чтобы получить вещи работать для личного тестирования или шоссе или т.д ... правильный способ борьбы с этим является пул потоков с рабочими потоками, назначенными задачами, как это предусмотрено комментарием Вдохновленного.

Смежные вопросы