2015-01-08 72 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); 
    } 

} 

這只是一個簡單的解決辦法得到的東西私人測試或硬件或等..處理這個問題的正確方法工作是一個線程池工作者線程根據Inspired的評論提供了任務。