2011-10-29 100 views
1

我目前正在嘗試實現一個(T)LV協議以用於TCP之上。這個協議的一個非常早期版本是通過每send-recv對發送一個消息來構建的。 (即發送(「消息發送」 - recv(...))。這是非常糟糕的帶寬明智的 - 我想因爲我發送非常小的數據包 所以現在我試圖切換到LV協議,一次只能通過他們各自的長度分隔(現在我使用Protocol Buffers序列化我的數據)發送幾條消息通過TCP實現TLV協議

我現在有兩個問題:

  • 在Python中我做

    sock.send(struct.pack("<H", len(gtMessage.SerializeToString()))) sock.send(gtMessage.SerializeToString())

如果我現在把它放到一個循環中,併發送了幾個這些消息,我最終會遇到我的老問題,據我所知。我能以某種方式將字符串串起來發送嗎?

  • 在C++中,首先接收消息的長度,然後讀取長度字段指示的字節數。

首先從TCP讀取所有內容然後解析它,或者我可以讀取一條消息,然後解析它,然後只讀取下一個位?

編輯:所以做一些更多的研究後,我會改寫的第一個問題是:

sock.send("somestring") 
    sock.send("somestring") 

一樣

sock.send("somestring"+"somestring") 

回答

1

做兩個連續發送可能會導致兩個實際的數據包出去,這並不是很好。要解決這個問題,您可以自己連接這兩個部分,或在第一次發送時使用writev(又名「收集寫入」)或TCP_CORK以防止它自己變成一個數據包。對於接收方來說,你應該得到一個大塊(儘可能達到一些合理的限制,比如幾兆字節或者某個東西),然後解析它。不要試圖只接收一個或兩個字節的大小,然後再接收另一個字節 - 這是效率低下的,如果發送的消息被分段,您仍然可能會以「短讀」結束。