2009-06-25 48 views
9

我正要寫一個通過TCP流的消息協議。接收者需要知道消息邊界在哪裏。寫一個流協議:消息大小字段或消息分隔符?

我可以發送1)固定長度的消息,2)大小字段,因此接收者知道消息有多大,或者3)唯一的消息終止符(我想這不能用在消息的任何其他地方) 。

爲了提高效率,我不會使用#1。

我喜歡#2,但它有可能使流不同步?

我不喜歡想法#3,因爲它意味着接收者無法提前知道消息的大小,並且還要求終結符不會出現在消息的其他地方。

#2,如果有可能不同步,我可以添加一個終止符,或者我保證永遠不會失去同步,只要發送者程序發送的內容是正確的。是否有必要做#2 AND#3?

請讓我知道。

感謝, JBU

回答

5

您使用的是TCP,數據包傳送的可靠性。所以連接要麼丟失,要麼超時,要麼讀完整條消息。 所以選項#2是好的。

3

根據您的工作級別,#2實際上可能不會出現與同步不同步的問題(TCP在數據包中包含序列號,並且如果到達時按照正確的順序爲您重新組裝流無序)。

因此,#2可能是您最好的選擇。此外,在傳輸過程中儘早瞭解消息的大小會使接收端更容易分配內存。

+0

_另外,在傳輸的早期就知道消息的大小,這樣可以更容易地在接收端分配內存。一句關心的話:確保限制分配多少內存。否則,您很容易受到使用自定義數據包的DDoS攻擊,這些數據包的大小字段爲2^32-1(或者您的整數大),從而快速填滿您的內存。 – Kenji 2017-04-21 18:13:48

1

如果您是從頭開發傳輸和接收代碼,那麼使用長度頭文件和分隔符都不會有什麼壞處。這將提供健壯性和錯誤檢測。考慮一下你只使用#2的情況。如果您向TCP流中寫入長度爲N的字段,但最終發送的消息大小與N不同,則接收端不會知道任何更好的消息,並最終導致混淆。

如果同時使用#2和#3,雖然不是萬無一失,但如果在從TCP流中消耗N個字節後遇到分隔符,則接收方可以更加確信它收到了正確的消息。您還可以安全地在郵件中使用分隔符。

查看HTTP Chunked Transfer Coding瞭解使用#2和#3的真實世界示例。

2

我同意sigjuice。 如果您有一個大小字段,它不是必需添加和消息結束分隔符 - 但是,這是一個好主意。兩者都使得事情更健壯,更容易調試。

考慮使用標準netstring format,其中包括一個大小字段和一個字符串結束字符。 因爲它有一個大小字段,所以在消息內部使用字符串末尾字符是可以的。

0

還有第四種選擇:自描述協議,如XML。

+0

這不適用於純二進制消息。它基本上是選項#3,但比單個分隔符差得多。 – Lucretiel 2015-01-06 20:38:07

2

有趣的是,這裏沒有明確的答案。無論如何,#2對於TCP來說都是安全的,並且經常在「現實世界」中完成。這是因爲TCP保證所有的數據都是無損的並且按照發送的順序到達,因此正確的實現不可能不同步。