2017-01-16 130 views
2

如何保持連接從連接的客戶端偵聽?在下面的代碼中,線程接收數據並回復客戶端並斷開連接。我想把接收和發送的過程放在循環中。我怎樣才能做到這一點 ?如何接收和發送數據從服務器到客戶端循環

void *thread_handle_connection(void *arg) { 
    char buffer[MAX_MSG_SIZE]; // Receive buffer 
    int bytes_read; 

    do { 

    // If there aren't any connections, sleep and recheck every second 
    while(!num_connections && !term_requested) { 
     sleep(1); 
    } 

    // Lock out connections queue and grab the first one 
    pthread_mutex_lock(&queue_mutex); 
    int connectionfd = remove_connection_from_queue(); 
    pthread_mutex_unlock(&queue_mutex); 

    if(-1 == connectionfd) { 
     continue; 
    } 

    // pthread_barrier_wait(&barrier); // Barrier for threads - for testing only 

    // Read up to 1024 bytes from the client 
    bytes_read = recv(connectionfd, buffer, MAX_MSG_SIZE - 1, 0); 

    // If the data was read successfully 
    if(bytes_read > 0) { 
     // Add a terminating NULL character and print the message received 
     buffer[bytes_read] = '\0'; 

     // Calculate response 
     int multiplicand = atoi(buffer); 
     char *response; 
     asprintf(&response, "%d", multiplicand * MULTIPLIER); 

     // Echo the data back to the client; exit loop if we're unable to send 
     if(-1 == send(connectionfd, response, strlen(response), 0)) { 
     warn("Unable to send data to client"); 
     break; 
     } 
     free(response); 
    } 

    // Close connection 
    close(connectionfd); 

    } while(bytes_read > 0 && !term_requested); 

    return NULL; 
} 
+1

你到底在問什麼? – zmbq

+2

那麼在實際的循環中包裝接收代碼將是一個好的開始。然後只需在該循環中讀寫,直到出現錯誤或連接關閉。 –

回答

0

首先,recv功能並不能保證你看的已經被寫入發送者的一切。您可能會收到部分數據(例如,發件人可能會發送10KByte,但第一次讀取時接收人可能會收到1.5K)。

其次,send函數不能保證它發送你要求的所有東西。如果不是所有東西都已發送,您需要發送其餘的答案。

第三,TCP是面向流的。這意味着你需要將一條消息與另一條消息分開。對於基於文本的協議,通常使用「新行」來達到此目的。

放在一起。如果你想申請永久連接,你需要:

  • 定義請求和響應分離
  • 保持讀取緩衝
  • 讀取所有數據到緩衝區,並掃描它要求分離器與反應分離器
  • 發送響應

如果你想在網絡編程中取得成功,你可能想了解一些關於非阻塞操作和輪詢/選擇功能的知識。

相關問題