簡體   English   中英

send() 和 recv() 的奇怪行為

[英]Weird behavior of send() and recv()

抱歉英語不好

為什么如果我在服務器上有兩個send() -s,在客戶端有兩個recv() -s,有時第一個recv()會從服務器獲取第二個send()的內容,而不只是獲取內容第一個並讓另一個recv()獲取另一個send()的“應有的和適當的”內容?

我怎樣才能以其他方式獲得這項工作?

這是設計使然。

TCP 流是可以在兩個端點之間發送字節的通道,但傳輸是基於流的,而不是基於消息的。

如果你想發送消息,那么你需要對它們進行編碼......例如,通過預先設置一個“大小”字段,該字段將通知接收者期望正文的字節數。

如果您先發送 100 個字節,然后再發送其他 100 個字節,則接收器很可能會在兩個不同的讀取命令中一次看到 200 個,甚至 50 + 150 個。 如果您想要消息邊界,那么您必須自己將它們放入數據中。

有一個較低的層(數據報)允許發送消息,但是它們的大小有限並且無法保證交付(即消息可能會丟失,會重復或您發送的兩條消息將以不同的方式到達命令)。 TCP 流建立在此數據報服務之上,並實現了在兩個端點之間可靠傳輸數據所需的所有邏輯。

作為替代方案,有一些旨在提供端點之間可靠消息傳遞的庫,例如ZeroMQ

很可能您使用 SOCK_STREAM 類型的套接字。 這是一個 TCP 套接字,這意味着您將數據推送到一側,它以相同的順序從另一側獲取,並且不會丟失塊,但沒有分隔符。 所以send()只是發送數據,而recv()接收當前時刻可用的所有數據。

您可以使用 SOCK_DGRAM,然后將使用 UDP。 但在這種情況下,每個send()都會發送一個數據報,而recv()會接收它。 但是你不能保證你的數據報不會被打亂或丟失,所以你必須自己處理這些問題。 最大數據報大小也有限制。

或者您可以堅持使用 TCP 連接,但您必須自己發送分隔符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM