2011-12-02 109 views
0

這次我編寫了一個聊天服務器和客戶端。這個想法是這樣的。兩個客戶端之間的同步傳輸消息

服務器對readfd(FD_SET)使用select方法來查找連接的客戶端上有哪些要發送的內容。如果它發現了一些東西,它會將它發送給其他客戶。

以下是服務器上的選擇功能和服務器的一部分code

SelectResults = select(maxDescriptor+1,&BackUpfdread,NULL,NULL,&time); 

我用select函數在客戶端也讓它尋求傳入和outcoming消息。(這些是服務器從其他客戶端發送這些,這個客戶要發送)。

那麼,select函數中的客戶端有一個fdread和fdwrite(FD_SET)。

Here是客戶端用於連接和聊天的代碼的一部分。

問題是,如果我連接服務器上的兩個客戶端郵件傳輸不是併發的,這意味着客戶端無法正確聊天。

最後我想在服務器中使用線程。一個等待接收和一個發送給客戶的線程,但我想聽到你的意見。

在此先感謝。

+0

你確實使服務器的監聽和客戶端套接字無阻塞? –

+0

對不起,但我不明白你的問題。 –

+0

它可能與套接字的阻塞或非阻塞狀態無關(使用谷歌搜索找出它的含義),但如果我正確理解你的問題,你的服務器工作時,只有一個客戶端連接,但不工作當兩個客戶端連接?那麼這是服務器而不是客戶端的問題。你可以編輯你的問題,包括小的相關服務器代碼片段(比如你如何調用'select'和'accept',以及如何從客戶端讀取數據並向客戶端發送數據)? –

回答

0

在客戶端中,您並不需要從0到maxDescriptor的循環。只需檢查是否設置了ConnectSocket。事情是這樣的:

// Main loop starts here 
for(; ;) 
{ 
    memset(SentBuff, 0, sizeof(SentBuff)); 
    printf("Write: "); 
    gets_s(SentBuff, sizeof(SentBuff)); 

    // Copy the fdread into BackUpfdread and fdwrite to BackUpfdwrite. 
    BackUpfdread = fdread; 
    BackUpfdwrite = fdwrite; 

    SelectResults = select(maxDescriptor+1,&BackUpfdread,&BackUpfdwrite,NULL,&timer); 

    if(SelectResults == -1) 
    { 
    perror("Client-select() error!\n"); 
    exit(1); 
    } 

    if (FD_ISSET(ConnectSocket, &BackUpfdread)) 
    { 
    RecvBytes = recv(ConnectSocket, RecvBuff, sizeof(RecvBuff), 0); 
    if(RecvBytes > 0) 
    { 
     printf("%s\n",RecvBuff); 
     // Cleaning the Receive Buffer 
     memset(RecvBuff,0,sizeof(RecvBuff)); 
    } 
    } 

    if (FD_ISSET(ConnectSocket, &BackUpfdwrite)) 
    { 
    SentBytes = send(ConnectSocket, SentBuff,sizeof(SentBuff),0); 
    // Cleaning the Sent Buffer 
    memset(SentBuff,0,sizeof(SentBuff)); 
    } 
} // Main loop ends here 

另外不要忘記從sendrecv檢查錯誤。尤其是recv非常重要,因爲它會告訴你服務器已斷開連接。

編輯:需要注意的另一個重要的事情是,插座是可寫始終,因此增加一個檢查,如果有什麼你檢查前如果套接字寫來寫。