2015-12-25 59 views
-1

最近我一直在嘗試製作一個客戶機/服務器程序來解決一些套接字問題。到目前爲止,我已經取得了成功,但似乎我遇到了障礙。對於一些快速的背景資料,我做了可以接受的連接的服務器,並完成所有設置和客戶端建立連接,這個代碼塊開始exectue:使用套接字清除讀取()緩衝區

while(1){ 
     read(newsockfd, &inbuffer, 256); 


     std::cout << "Message from client " << inet_ntoa(cli_addr.sin_addr) << " : "; 
     for(int i = 0; i < sizeof(inbuffer); i++){ 
      std::cout << inbuffer[i]; 

     } 
     std::cout << std::endl; 

} 

現在客戶只需,執行時連接到服務器並寫入套接字,然後退出。因此,由於發送了一條消息,此循環只應運行一次,然後等待另一條消息,如果我讀的是正確的。

但是最終發生的是這個循環一遍又一遍地反覆打印同樣的信息。從我讀到的(在本網站和其他網站上)關於read()函數的是,在它被調用一次之後,它等待另一個消息被接收。我可能在這裏犯了一個愚蠢的錯誤,但是有什麼辦法可以讓這個read()函數等待一條新消息,而不是一遍又一遍地使用同一條舊消息?還是有另一個函數可以取代read()來做我想做的事情?

感謝您的任何幫助。

+1

請勿爲無關語言添加標籤。 C不是C++不是C – Olaf

+0

我把C放在C中,因爲使用的一些庫是C – Sock314

回答

1

您不檢查返回值read。因此,如果另一端關閉連接或出現錯誤,您只需循環輸出緩衝區中發生的任何事情。您可能想要:

while(1){ 
    int msglen = read(newsockfd, &inbuffer, 256); 
    if (msglen <= 0) break; 

    std::cout << "Data from client " << inet_ntoa(cli_addr.sin_addr) << " : "; 
    for(int i = 0; i < msglen; i++){ 
     std::cout << inbuffer[i]; 
    } 
    std::cout << std::endl; 

} 

請注意,我已將單詞「消息」更改爲「數據」。原因如下:

因此,由於發送了一條消息,此循環應該只運行一次,然後等待另一條消息,如果我讀的是正確的。

這是不正確的。上面的代碼沒有任何「消息」的概念,並且TCP不保留應用程序消息邊界。因此,這不僅是錯誤的,也不可能是正確的,因爲「消息」一詞沒有任何意義,可能適用於這種情況。 TCP不會將單次調用中要傳遞的字節「粘合在一起」到發送函數。