2013-04-26 50 views
0

我有點通過Unix套接字(TCP本地)插槽清洗

弄得我有一個服務器客戶

  • 客戶通過套接字發送一些信息到服務器(使用send) 多次
  • 服務器打印此數據(se rver致電recv接收它)。

的問題是,服務器版畫不僅我想,插座在某種程度上這是由客戶發送的最後信息,但一些老的信息(有時損壞)從此客戶太多,所以通過客戶端積累了所有寫入它的以前的數據

如何才能服務器只接收從客戶端最後的數據?我應該以某種方式清理套接字,否則我應該一直關閉它並創建新的(非常糟糕的解決方案)?

+1

你能發佈代碼嗎?儘管保留它[SSCCE](http://sscce.org/)! – Kninnug 2013-04-26 19:39:21

+0

它不能。例外是具有緩衝區溢出的UDP,但它無論如何都做你想要避免的 – 2013-04-26 19:39:36

+0

TCP連接創建沒有明確界限的數據流。數據邊界是應用程序定義的。您的應用程序必須準備好進行部分接收操作,並能夠檢測到接收完整數據的時間。這意味着它可能需要多次調用recv函數來接收由對等方發送的完整數據。 – 2013-04-26 19:42:30

回答

3

TCP套接字是流套接字。
這意味着您發送的所有數據不會被視爲一系列消息,而會被視爲一系列字節。這些字節是按順序接收的,沒有增加或省略,但不一定在相同的塊中。

例如,如果您的客戶端每次調用send 3次,每次1000字節,則無法知道recv將返回數據的次數。它可能會返回3次,每個1000字節,或者只有一次3000字節,或理論上甚至3000次,每次1字節。

+1

對ugoren剛纔所說的+1。您需要檢查recv()的返回值以確定您實際獲得的字節數。許多套接字程序員犯的最大錯誤是假定「recv()」將返回與傳遞給「send()」相同數量的字節。 – selbie 2013-04-26 20:16:58

1

圖像發送/接收的字節放置在一個隊列(內部緩衝區)中。如果您撥打send()兩次,每次發送10個字節,則緩衝區中將有20個字節。當另一方調用recv()時,它將從該隊列中取出若干字節並將它們放入數組中。多少字節?直到可用(20)或更少。

例如,如果調用

nb = recv(socket, arr, 15,...); 

那麼只有15個字節將被消耗(大概您的陣列arr有這個長度)時,它們將被複制到arrnb將是15,並在內部我們留下了5個字節的緩衝區。

如果相反,我們會打電話

nb = recv(socket, arr, 100,...); 

那麼20個字節數據將被複制到arrnb將是20,和內部緩衝區將是空的。

這顯示這一點:

  • send()/recv()電話是在一個一一對應

  • 你必須經常檢查recv回報(nb)知道有多少字節是讀

  • 你可以不知道哪些字節是在每個發送電話。的「信息」的界定是你

  • 你是不讀的消息,也沒有字符串(空值終止字符數組),你只是讀取字節。然後,你不能只是叫printf("%s",arr)看到接收的字節

1
  1. TCP是流協議;

  2. 檢查send和recv的返回值,確保差錯已得到妥善處理;

  3. 檢查你打印的是你送什麼,檢查二進制內容和長度發送和recv緩衝區。

確保您在發送方發送的內容是您在接收方獲得的內容。

和一塊代碼是公理解用於進一步分析。