我有點通過Unix套接字(TCP本地)插槽清洗
弄得我有一個服務器和客戶:
- 客戶通過套接字發送一些信息到服務器(使用
send
) 多次 - 服務器打印此數據(se rver致電
recv
接收它)。
的問題是,服務器版畫不僅我想,插座在某種程度上這是由客戶發送的最後信息,但一些老的信息(有時損壞)從此客戶太多,所以通過客戶端積累了所有寫入它的以前的數據。
如何才能服務器只接收從客戶端最後的數據?我應該以某種方式清理套接字,否則我應該一直關閉它並創建新的(非常糟糕的解決方案)?
我有點通過Unix套接字(TCP本地)插槽清洗
弄得我有一個服務器和客戶:
send
) 多次recv
接收它)。的問題是,服務器版畫不僅我想,插座在某種程度上這是由客戶發送的最後信息,但一些老的信息(有時損壞)從此客戶太多,所以通過客戶端積累了所有寫入它的以前的數據。
如何才能服務器只接收從客戶端最後的數據?我應該以某種方式清理套接字,否則我應該一直關閉它並創建新的(非常糟糕的解決方案)?
TCP套接字是流套接字。
這意味着您發送的所有數據不會被視爲一系列消息,而會被視爲一系列字節。這些字節是按順序接收的,沒有增加或省略,但不一定在相同的塊中。
例如,如果您的客戶端每次調用send
3次,每次1000字節,則無法知道recv
將返回數據的次數。它可能會返回3次,每個1000字節,或者只有一次3000字節,或理論上甚至3000次,每次1字節。
對ugoren剛纔所說的+1。您需要檢查recv()的返回值以確定您實際獲得的字節數。許多套接字程序員犯的最大錯誤是假定「recv()」將返回與傳遞給「send()」相同數量的字節。 – selbie 2013-04-26 20:16:58
圖像發送/接收的字節放置在一個隊列(內部緩衝區)中。如果您撥打send()
兩次,每次發送10個字節,則緩衝區中將有20個字節。當另一方調用recv()
時,它將從該隊列中取出若干字節並將它們放入數組中。多少字節?直到可用(20)或更少。
例如,如果調用
nb = recv(socket, arr, 15,...);
那麼只有15個字節將被消耗(大概您的陣列arr
有這個長度)時,它們將被複制到arr
,nb
將是15,並在內部我們留下了5個字節的緩衝區。
如果相反,我們會打電話
nb = recv(socket, arr, 100,...);
那麼20個字節數據將被複制到arr
,nb
將是20,和內部緩衝區將是空的。
這顯示這一點:
send()
/recv()
電話是不在一個一一對應
你必須經常檢查recv
回報(nb
)知道有多少字節是讀
你可以不知道哪些字節是在每個發送電話。的「信息」的界定是你
你是不讀的消息,也沒有字符串(空值終止字符數組),你只是讀取字節。然後,你不能只是叫printf("%s",arr)
看到接收的字節
TCP是流協議;
檢查send和recv的返回值,確保差錯已得到妥善處理;
檢查你打印的是你送什麼,檢查二進制內容和長度發送和recv緩衝區。
確保您在發送方發送的內容是您在接收方獲得的內容。
和一塊代碼是公理解用於進一步分析。
你能發佈代碼嗎?儘管保留它[SSCCE](http://sscce.org/)! – Kninnug 2013-04-26 19:39:21
它不能。例外是具有緩衝區溢出的UDP,但它無論如何都做你想要避免的 – 2013-04-26 19:39:36
TCP連接創建沒有明確界限的數據流。數據邊界是應用程序定義的。您的應用程序必須準備好進行部分接收操作,並能夠檢測到接收完整數據的時間。這意味着它可能需要多次調用recv函數來接收由對等方發送的完整數據。 – 2013-04-26 19:42:30