2011-05-22 19 views
3

我有一個客戶端,將數據發送到服務器2個的連續發送呼叫:可以通過一次recv()調用從2個連續的send()調用中接收數據嗎?

send(_sockfd,msg,150,0); 
send(_sockfd,msg,150,0); 

和服務器接收時,第一個發送呼叫發送(比方說,我正在使用選擇):

recv(_sockfd,buf,700,0); 

請注意,我收到的緩衝區要大得多。

我的問題是:有沒有任何機會,buf將包含兩個消息?我需要2 recv()調用來獲得這兩個消息?

謝謝!

回答

4

TCP流定向協議。不以消息/記錄/塊爲導向。也就是說,所有的保證是,如果你發送一個流,字節將按照你發送的順序到達另一端。 RFC 793或任何其他文件沒有規定涉及的分段/數據包的數量。

這與UDP形成鮮明對比。正如@R ..所說的,在UDP中,整個消息是在一個操作中發送的(注意術語變化:message)。嘗試使用TCP發送巨大的消息(比MTU大幾倍)?沒關係,它會爲你分割它。

在本地網絡或本地主機上運行時,您一定會注意到(通常)one send == one recv。不要以爲。有些因素可以顯着改變它。在這些

  • 內格爾
  • 標的MTU
  • 內存使用(可能)
  • 定時器
  • 許多其他

當然,不具有一個send和一個之間的對應關係recv是一個滋擾,你不能依靠UDP。這是SCTP的原因之一。 SCTP是一個非常有趣的協議,它是面向消息的

返回TCP,這是一個常見的麻煩。同樣常見的解決方案是這樣的:

  • 建立所有分組開始的固定長度序列(說32個字節)
  • 這些32個字節包含(除其他事項外可能的)消息的大小
  • 當您從套接字讀取任何數量的數據時,將數據添加到特定於該連接的緩衝區中。當到達32 字節時,請閱讀您需要閱讀的長度,直到您收到消息。

真的很重要的是要注意線路上是否真的沒有消息,只有字節。一旦你理解了它,你將在編寫網絡應用程序方面取得巨大飛躍。

0

是的,它可以並且經常。使用TCP/IP時無法匹配發送和接收呼叫。你的程序邏輯應該在循環中測試send和recv調用的返回值,當所有事情都被髮送或接收時,該循環終止。

1

答案取決於套接字類型,但總的來說,是的,這是可能的。對於TCP來說,這是常態。對於UDP我相信它不會發生,但我不是網絡協議/編程方面的專家。

相關問題