2015-10-14 86 views
0

我寫了一個簡單的C套接字程序,它向服務器發送一個INIT包以指示準備文本傳輸。服務器當時不會發回任何數據。 發送INIT包後,客戶端發送GET包並等待來自服務器的數據塊。 因此,每次服務器收到GET包時,它都會向客戶端發送一大塊數據。將讀取(套接字)塊,直到緩衝區已滿?

到目前爲止這麼好。緩衝區的大小爲512字節,大塊爲100字節,加上一點點大開銷。

但我的問題是客戶端沒有收到第二條消息。

所以我的猜測是,read()會blpck,直到緩衝區已滿。這是正確的還是可能的原因?

+2

不,「read()」會讀取它的所有內容。它只會在阻塞模式下阻塞,當沒有數據並且沒有其他事件掛起時。 –

+0

謝謝。那麼問題是什麼?難道第二封郵件發送得太快了嗎? – Ctwx

+0

不需要。即使它在客戶端發送數據之前發送,您也可以讀取它,因爲它是流套接字操作的方式。它可能是這樣的,服務器還沒有收到完整的請求,因此不會發送回應。例如,在HTTP協議中,服務器在讀取所有請求標題+換行符之前不會開始回覆。所以檢查那部分。 –

回答

-3

沒有,讀不阻止調用的回答,您可以參考下面的點來猜測錯誤

幾個檢查點,你可以找到:

  1. 找出讀的是在第二次返回。
  2. memset緩衝區每次都在recv前
  3. 如果無法輸出則使用fflush(stdout)。

確保所有三個都存在。如果問題尚未解決,請在此處發佈源代碼

+1

memset緩衝區..... :(( –

+3

這樣一堆noncence作爲接受的答案... – SergeyA

1

這取決於。對於TCP套接字read可能會在緩衝區已滿之前返回,並且您可能需要在循環中接收以獲取完整的消息。對於UDP套接字,您讀取的大小通常是單個數據包(數據報)的大小,然後read可能會阻塞,直到它讀取了所有請求的數據。

+0

好吧,這是一個tcp插座,我忘了提及。我沒有設置任何套接字選項。那麼緩衝區是否已滿,read()會繼續?根據你的回答:不。但爲什麼會發生這種情況?第二個包發送得太快了嗎? – Ctwx

+1

@Ctwx當您使用TCP時,套接字API不處理數據包。如果你想通過TCP發送你自己的消息,你需要一種方法來知道這樣的消息從哪裏開始以及它在哪裏結束。你的read()調用可以讀取4條消息,或者它可以讀取消息的1/3 - 這是你需要處理的。 – nos

1

答案是否定的:read()在tcp/ip套接字不會阻塞,直到緩衝區已滿。如果有任何數據可用,即使您的套接字被阻塞,並且您請求的數據超過了可用數據,read()也會立即返回。

請記住,TCP/IP是一個字節流協議,你必須這樣對待它。接口沒有義務將數據一起傳輸到單個數據包中,只要它按照您將其放入套接字的順序呈現給您。