2013-10-17 127 views
0

嗨我新來的套接字編程C.現在我工作在聊天程序,我成功可以發送和接收消息,但問題是當客戶端請求發送用戶列表,客戶端在線和一旦服務器發送消息回到客戶端,消息成功打印當前連接的客戶端的列表,但是一旦顯示它不會退出循環。下面只是代碼的一部分。接收多個消息套接字編程C

服務器側(server.c)

pthread_mutex_lock(&list_mutex); 
    for(i =0; i < NotEndOfList; i++) 
    { 

    sprintf(message_replay, "Server: %s \n", usersList[i].name); 
    write(sock , message_replay , strlen(message_replay)); 

    } 
    pthread_mutex_unlock(&list_mutex); 

客戶端側(Client.c)

int i =0; 
      while(i < NotEndOfList) 
     { 
      if(recv(sock , server_reply , 2000 , 0) < 0) 
      { 
       puts("recv failed"); 
       break; 
      } 
     i++; 

     puts(server_reply); 
     } 

樣本輸出

User A -->: 
    //List 
    User A 
    User B 
    User C 
    // Loop 

正確的樣本輸出

User A -->: 
//List 
User A 
User B 
User C 
User A -->: 

非常感謝

+0

無法保證每次在服務器上寫入'write'的調用都會導致整個消息被客戶端中的單個'recv'讀取。您可能需要重複調​​用'recv'來閱讀單個消息。相反,對'recv'的單個調用可能會將來自多個調用的數據返回到'write'。你需要定義一個簡單的協議,並用它來決定在客戶端收到多少個消息 – simonc

回答

0

如果所有消息的大小相同,則可以使用此解決方案。我不知道你的message_replay的大小,我們只是說它的類型char[256]

在服務器

而不是使用strlen()你可以隨時發送256個字節。客戶端將忽略空終止符後的所有結尾字符。然後

write(sock , message_replay, 256); // or sizeof(message_replay) if it's static 

在客戶

客戶應該期望所有的消息爲256個字節長。循環運行直到收到所有256個字符,並在每個循環附加receive_buffer[]。計數器會記錄我們收到的字節數以及缺少的字節數。

for (int i = 0; i < NotEndOFList; i++) { 
    char receive_buffer[256]; 
    int received_bytes = 0; 
    int remaining_bytes = sizeof(receive_buffer); 

    while (remaining_bytes > 0) { 
     int res = recv(sock , &receive_buffer[received_bytes] , remaining_bytes, 0); 
     if (res < 0) { 
      puts("recv failed"); 
      break; 
     } 
     received_bytes += res; 
     remaining_bytes -= res; 
    } 

    puts(receive_buffer); 
} 

PS!我沒有測試過,如果你決定使用它,請告訴我它是如何運行的。

+0

Btw,你應該以某種方式檢查receive_buffer是否真的包含一個空終止符字符,或者只是爲了確保在最後添加一個。在while循環之後,你可以做'receive_buffer [sizeof(receive_buffer)-1] ='\ 0''。如果服務器決定發送一個沒有空終止符的消息,'puts()'命令將不知道在哪裏停止讀取(當它開始從'received_bytes'的存儲區讀取時,它可能會停止,這是太晚了 – Atle

+0

我會明天再試,讓你知道btw message_replay是一樣的大小 –